perm filename X3J13[X3,LSP] blob sn#871543 filedate 1989-03-24 generic text, type T, neo UTF8
∂01-Mar-89  1109	X3J13-mailer 	Section 1.7
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 1 Mar 89  11:09:32 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA00298; Wed, 1 Mar 89 11:07:25 PST
Message-Id: <8903011907.AA00298@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
	for x3j13@sail.stanford.edu; id AA00298; Wed, 1 Mar 89 11:07:25 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 1 Mar 89 07:23
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: Section 1.7

%%Language Extensions
[{\it This section is dependent upon the passage or failure of the following
issues: EXTENSIONS-POSITION, EXTRA-SYNTAX, EXTRA-OPTIONAL-KEYWORD-ARGUMENTS,
UNSPECIFIED-DATATYPTES, UNSOLICITED-MESSAGES, MACRO-AS-FUNCTION, and 
EXTRA-RETURN-VALUES. When they have passed or failed, this section
will be altered.}]

A language extension is
any implementation-supplied {\word tool} that isn't explicitly defined
in this standard. This includes facilities added to {\word tools} defined
in this standard.
An implementation may have extensions,
provided they do not alter the behavior of conforming code and
provided they are not explicitly prohibited by this standard.

          
From Common Lisp's point of view, defining an extension
refers to a facility's initial definition.
Whether an implementation permits redefinition of an extension is between that
implementation and its users and beyond the scope of this standard to
specify. 
 

If this standard says that ``the results are unspecified", and an
implementation specifies the results, this an extension in the
sense that if the correct behavior of a program depends on the results,
only implementations with the same extension will execute the program
correctly.

In places where the standard says that ``an implementation may be extended",
this implies that a conforming, but probably non-portable, program can
be written using the implementation's extension.
%Following will be included if the proposal that states this is passed.
%An implementation is required to have a way to disable its extensions, so
%that a programmer can be told when he is using a feature that might
%affect his program's portability. 

The following list contains specific guidance to implentations 
concerning certain types of extensions.
\beginlist
\itemitem{\bf Additional syntax}

An implementation
is not allowed to extend {\word macros} and {\word special forms} to take
additional syntax not specified in this standard.
 
\itemitem{\bf Extra optional or named arguments}
 
Unless explicitly allowed in this standard, 
implementations are not allowed to include definitions
of {\word functions} with extra optional or named arguments
with system-dependent meanings.

When extra optional or named arguments are allowed by this
standard, they will be annotated as follows:
{\word functions} that may be
extended to take implementation-specific optional arguments are indicated
by {\tt &rest ignore} in their argument list.
{\word Functions} that may be extended
to take additional keyword parameters are indicated by {\tt &allow-other-keys}. 
 
The goal is not to outlaw any extensions currently offered by
implementors, but to make the range of extensions to {\word functions} 
defined in
this standard well documented in this standard.  Implementations that want to
extend {\word functions} that aren't explicitly 
allowed to be extended can instead
shadow them.

% or as follows, if this proposal passes.
%Alternate proposal: NOT-IN-STANDARD-PACKAGE
% 
%Like NO-EXCEPT-AS-ALLOWED, except that an implementation may always
%provide additional named arguments to a function if the names are not in
%an implementation-specific package (the list of these currently includes
%the LISP, USER, and KEYWORD packages).
% 

\itemitem{\bf Extra return values}

 
Unless it is explicitly allowed in this standard,
an implementation  is 
not allowed to return extra values from {\word functions}
defined by this standard.

\itemitem{\bf Function behavior on non-standard data types}

An implementation does not define the behavior of {\word functions}
on data types not explicitly permitted by this standard. 

\itemitem{\bf Unsolicited messages}

Unsolicited messages, such as garbage collector notifications 
and autoload heralds, if
they are produced by an implementation, should not be directed to
@var[standard-output] or @var[error-output]\rm. 
If an implementation produces them, they
may be produced on a {\datatype stream} 
that is not shared with any of the {\datatype streams}
that a user might redefine or redirect. This means that an
implementation is allowed to
direct such notifications to @var[terminal-io] since a user may not redirect
@var[terminal-io]\rm.
 
Messages such as progress reports from {\function load} and 
{\function compile} are solicited,
and are not covered here. 
 
\itemitem{\bf Implementation of macros and special forms}

Operators that are defined as {\word macros} or
{\word special forms} may be defined as {\word
functions}
instead if the semantics can be preserved. 

%or as follows:
%Alternate Proposal: MACRO-AS-FUNCTION:STATUS-QUO
%
%The standard will remain silent on the issue of whether or not is
%is legal for an implementation to implemention "macros" and 
%"special forms" as functions.

%or as follows:
%Alternate Proposal: MACRO-AS-FUNCTION:DISALLOW
%
%A conforming implementation does not define "macros" and "special forms"
%as functions.
\endlist

∂01-Mar-89  1111	X3J13-mailer 	Section 5.2
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 1 Mar 89  11:10:51 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA00392; Wed, 1 Mar 89 11:08:46 PST
Message-Id: <8903011908.AA00392@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
	for x3j13@sail.stanford.edu; id AA00392; Wed, 1 Mar 89 11:08:46 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 1 Mar 89 07:25
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: Section 5.2

%% Input/Output
It is possible to perform I/O to any device physically connected to
the machine on which the @xlisp\ system is running. 
Some implementations, however, may not support the interfaces
to all possible physical devices. Some external
data sources
are treated specially in @clisp. The following sections describe the file
system interface, binary and character I/O, and the {\function load}ing process.

\beginsubSection{Files}

%% 23.0.0 5
@clisp\ assumes that files are named, that given a name a 
{\datatype stream} can be constructed that
connects to a file of that name, and that the
names can be fit into a {\datatype pathname}.

%% 23.0.0 6
%Facilities are provided for manipulating {\datatype pathnames},
%for creating
%{\datatype streams} 
%connected to files, and for manipulating the file system
%through {\datatype pathnames} and {\datatype streams}.
%Left out.

%% 23.1.0 1
In general, different
file systems have different naming formats for files.
There are two ways to represent file names:
namestrings, which are {\datatype strings} 
in the implementation-dependent form
customary for the file system, and {\datatype pathnames}, which are
{\word objects} that represent file names in an implementation-independent
way.  {\word Functions} 
are provided to convert between these two representations,
and all manipulations of files can be expressed in machine-independent
terms by using {\datatype pathnames}. See ``Pathname''.

%% 23.1.0 2
%In order to allow code to operate in a network environment
%that may have more than one kind of file system, the pathname facility
%allows a file name to specify which file system (called the
%host) is to be used.
%Left out.

%%% 23.1.1 11
%Parsing is the conversion of a namestring 
%into a {\datatype pathname}. This operation is
%implementation-dependent, because the format of namestrings
%is implementation-dependent.
%
%Merging takes a {\datatype pathname} with missing components
%and supplies values for those components from a source of defaults.
%This operation is also implementation-dependent because the
%set of valid {\datatype pathnames} that may result from merging is
%implementation-dependent.

%% 23.2.0 1
The basic operations for opening a file are {\function open} and
{\function with-open-file}. The basic operation for closing a file
is {\function close}.


Rules concerning file I/O follow:
 
\beginlist 


%% 22.2.1 2
\itemitem{\bf Eof-error-p} 

{\arg Eof-error-p} in I/O {\word forms}
controls what happens if input is from a file (or any other
input source that has a definite end) and the end of the file is reached.
If {\arg eof-error-p} is true (the default), an error will be signalled
at end of file.  If it is false, then no error is signalled, and instead
the {\word form} returns {\arg eof-value}.

%% 22.2.1 4
\itemitem{\bf Recursive-p} 

If {\arg recursive-p} is 
supplied and not @nil\rm, it specifies that
this {\word form} 
call is not a {\word top level} call to {\function read} but an embedded call,
typically from the {\word function} for a macro character.
It is important to distinguish such recursive calls for three reasons.

%% 22.2.1 5
\beginlist
\itemitem{1.}
A {\word top level} call establishes the context within which the
{\tt \#n=} and {\tt \#n\#} syntax is scoped.  Consider, for example,
the expression

@lisp
 (cons '#3=(p q r) '(x y . #3#))
@endlisp
If the single quote macro character were defined in this way:

@lisp
 (set-macro-character #@bsl\ '
    #'(lambda (stream char)
         (declare (ignore char))
         (list 'quote (read stream))))
@endlisp

then the expression could not be read properly, because there would be no way
to know when {\function read} is called recursively by the first
occurrence of @f['] that the label @f[\#3=] would be referred to
later in the containing expression.
There would be no way to know because {\function read}
could not determine that it was called by a macro character function
rather than from {\word top level}.  The correct way to define the single quote
macro character uses {\arg recursive-p}: 

@lisp
 (set-macro-character #@bsl\ '
    #'(lambda (stream char)
         (declare (ignore char))
         (list 'quote (read stream t nil t))))
@endlisp

%% 22.2.1 6
\itemitem{2.}
A recursive call does not alter whether the reading process
is to preserve whitespace or not (as determined by whether the
{\word top level} call was to {\function read} or {\function
read-preserving-whitespace}).
Suppose again that single-quote had the first, incorrect, macro character
definition shown above.  Then a call to {\function read-preserving-whitespace}
that read the expression @f['foo ] would fail to preserve the space
character following the symbol @f[foo] because the single-quote
macro character function calls {\function read}, 
not {\function read-preserving-whitespace},
to read the following expression (in this case @f[foo]\rm).
The correct definition, which passes the value @true\ for {\arg recursive-p}
to {\function read}, allows the {\word top level} call to determine
whether whitespace is preserved.

%% 22.2.1 8
\itemitem{3.}
When end-of-file is encountered and the {\arg eof-error-p} argument
is not @nil\rm, the kind of error that is signalled may depend on the value
of {\arg recursive-p}.  If {\arg recursive-p} 
is not @nil\rm, then the end-of-file
is deemed to have occurred within the middle of a printed representation;
if {\arg recursive-p} is @nil\rm, then the end-of-file may be deemed to have
occurred between {\word objects} rather than within the middle of one.

\endlist

\endlist
\endsubSection%{Files}

\beginsubSection{Character and Binary Input/Output}



Figure {\chapno--\the\capno} lists reader and printer control variables.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
@var[read-base] & @var[read-suppress]  & @var[print-escape] \cr
@var[print-pretty] & @var[print-circle] & @var[print-base] \cr
@var[print-radix] & @var[print-case] & @var[print-gensym] \cr
@var[print-level] & @var[print-length] & @var[print-array] \cr
@var[read-default-float-format] & & \cr
\noalign{\vskip -9pt} }} 
\caption{Reader and printer control variables}                              
\endfig


Figure {\chapno--\the\capno} lists character and binary input 
stream {\word tools}.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt read }&{\tt  read-preserving-whitespace }&{\tt read-delimited-list }\cr
{\tt read-line }&{\tt  read-char }&{\tt  unread-char }\cr
{\tt peek-char }&{\tt  listen }&{\tt  read-char-no-hang }\cr
{\tt clear-input }&{\tt  read-from-string }&{\tt  parse-integer }\cr
{\tt read-byte }&{\tt  }&{\tt  }\cr
\noalign{\vskip -9pt} }} 
\caption{Character and binary input tools}                              
\endfig


Figure {\chapno--\the\capno} lists character and binary output
stream {\word tools}.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr           
\noalign{\vskip -9pt}                               
{\tt write }&{\tt  prin1 }&{\tt  print }\cr
{\tt pprint }&{\tt  princ }&{\tt  write-to-string }\cr
{\tt prin1-to-string }&{\tt  princ-to-string }&{\tt  write-char }\cr
{\tt write-string }&{\tt  write-line }&{\tt  terpri }\cr
{\tt fresh-line }&{\tt  finish-output }&{\tt  force-output }\cr
{\tt clear-output }&{\tt  write-byte }&{\tt  format }\cr
\noalign{\vskip -9pt} }} 
\caption{Character and binary output tools}                              
\endfig

{\function y-or-n-p} and 
{\function yes-or-no-p}  are used to query the user.

%% 2.2.2 6
When the character {\tt \#{\char '134}Newline} is written to an output file,
the implementation must take the appropriate action
to produce a line division.  This might involve writing out a
record or translating {\tt \#{\char '134}Newline} to a CR/LF sequence.

\endsubSection%{Character and Binary Input/Output}
\beginsubSection{Loading}
%% 23.4.0 1
To {\function load} a file is to treat its contents as code and execute
that code. The file may contain character data or binary data. If it is
charater data, {\function load}ing 
is accomplished essentially by sequentially reading
the {\word forms} in the file, evaluating each immediately after it is read.

%% 23.4.0 2
{\function Load}ing a compiled 
(``fasload'') file is similar, except that the file does not
contain text but rather pre-digested expressions created by the
compiler that can be {\function load}ed more quickly.
See ``Compilation''.
\endsubSection%{Loading}

∂01-Mar-89  1136	X3J13-mailer 	Section 1.5
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 1 Mar 89  11:36:49 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA02677; Wed, 1 Mar 89 11:34:49 PST
Message-Id: <8903011934.AA02677@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
	for x3j13@sail.stanford.edu; id AA02677; Wed, 1 Mar 89 11:34:49 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 1 Mar 89 07:23
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: Section 1.5

%%Compliance
[{\it If the issue, CONFORMANCE-POSITION, undergoes radical modification
before passage, this section will change. Therefore, passage of this
section and CONFORMANCE-POSITION go hand in hand.}]


A conformity clause is a statement that is not part of
the language definition, but specifies requirements for compliance with the
language standard.
The standard presents the syntax and semantics to be implemented by
a conforming implementation.

A conforming implementation is an implementation
that processes
code that is written 
in the language defined by the language standard, and
that obeys all the conformity clauses for 
implementations written in the language standard.


Requirements for a conforming implementation:
\beginlist
\itemitem{1.} A conforming implementation is one that correctly
translates and executes conforming code.
\itemitem{2.} A conforming implementation
is one that rejects all
code that contains errors whose detection is required by this standard.
\itemitem{3.} A conforming implementation is one that contains no
variation except where the language standard permits, and specifies all
such permitted variations in the manner prescribed by this standard.
See ``Language Extensions''.
\itemitem{4.} A conforming implementation includes the following
in its accompanying documentation:
\beginlist
\itemitem{a.} A list of all definitions or values for the 
implementation-defined features in the standard language.
See ``Implementation-defined Features''.
\itemitem{b.} A list of all the features of this implementation
which are not part of the standard language but which could unexpectedly
interact with user code, including all package names
and nicknames  the implementation
uses.
\itemitem{c.} A statement of conformity, giving the complete reference to
this standard.
\endlist     
\itemitem{5.} A conforming implementation shall meet the technical
specification in its accompanying documentation when related to the
requirements of this standard.
\itemitem{6.} A conforming implementation shall treat an
error as is outlined in ``Errors''.
\endlist

The basic test for conformance will be that code written to the letter 
of the standard will run in all conforming implementations.
The basic rules are as follows:
\beginlist
\itemitem{1.}
Conforming code uses only the syntax specified in the standard.
\itemitem{2.}
Conforming code is written in only the sequence specified in the standard.
\itemitem{3.}
Conforming code is written using only the {\word functions}, {\word  macros},
{\word special forms}, variables, and constants specified in this standard.
Use of language extensions to the syntax specified
in the standard, or dependence upon the existence of those extensions,
is not allowed in conforming code.
\itemitem{3.}
The definitions of all other {\word functions}, {\word macros}, or 
{\datatype symbols}
that are used by the code must accompany 
the code.
\itemitem{4.}
Conformance will not be machine-checkable.
\endlist


Portable code is required to produce equivalent results and 
observable side effects in all conforming implementations.   
It is possible for conforming code to
run in all conforming implementations, but to have allowable
implementation-dependent behavior that could make it non-portable.

∂01-Mar-89  1159	X3J13-mailer 	New versions of standard files available 
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 1 Mar 89  11:59:21 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA05099; Wed, 1 Mar 89 11:57:05 PST
Message-Id: <8903011957.AA05099@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
	for x3j13@sail.stanford.edu; id AA05099; Wed, 1 Mar 89 11:57:05 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 1 Mar 89 07:02
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: New versions of standard files available

New versions of the standard files that will be voted on in March are available
on hudson.dec.com. There will probably still be changes to section 5.1 (Errors),
so plan to copy and review that last. All these files are contained in
march-27-ballot.dvi, if you can use that file type. If you want to build this
yourself, use march-27-ballot.tex as well as the other files necessary for
any build (kcamfont.tex, kcmacros.tex, macros2.tex, march-27-ballot.tc).


S1100.SCOPE-PURPOSE-AND-HISTORY
S1200.ORGANIZATION-OF-THE-DOCUMENT
S1300.REFERENCED-PUBLICATIONS
S1400.DEFINITIONS
S1500.COMPLIANCE
S1600.IMPLEMENTATION-DEFINED-FEATURES
S1700.LANGUAGE-EXTENSIONS
S2100.INTRODUCTION
S2200.TYPES
S5100.ERRORS
S5200.INPUT-OUTPUT
S5300.INTERFACE-WITH-PROGRAMMING-ENVIRONMENT
S5400.GENERALIZED-REFERENCE


Please let me know if you have trouble accessing these files.
I will be mailing the sources to you for review.
kathy chapman

∂01-Mar-89  1203	X3J13-mailer 	Section 1.3
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 1 Mar 89  12:03:44 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA05782; Wed, 1 Mar 89 12:01:39 PST
Message-Id: <8903012001.AA05782@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
	for x3j13@sail.stanford.edu; id AA05782; Wed, 1 Mar 89 12:01:39 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 1 Mar 89 07:22
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: Section 1.3

%%Referenced Publications

\beginlist
\item{} {\it The Anatomy of Lisp}, John Allen, McGraw-Hill, 1978.
\item{} {\it Compile-time Evaluation and Code Generation for Semantics-directed
Compilers}, Andrew W. Appel, Carnegie-Mellon University, 1985.
\item{} {\it The Definition of Programming Languages}, Andrew D. McGettrick,
Cambridge University Press, 1980.
\item{} {\it Desiderata for the Standardisation of Lisp}, Julian Padget et.
al., 1986 ACM Conference on Lisp and Functional Programming, 1986.
\item{} {\it Formal Specification of Programming Languages - A Panoramic
Primer}, Frank G. Pagan, Prentice-Hall, Inc, 1981.
\item{} {\it $Revised↑3$ Report on the Algorithmic Language Scheme},
Jonathan Rees and William Clinger (editors), SIGPLAN Notices V21, \#12,
December, 1986.
%\item{} {\it Denotational Semantics}, David A. Schmidt, Allyn and Bacon,
%1986.
\item{} {\it Common LISP the Language}, Guy L. Steele, Jr., Digital Press,
1984.
%\item{} {\it Denotational Semantics: The Scott-Strachey Approach to Programming
%Language Theory}, Joseph E. Stoy, MIT, 1977.
\item{} {\it A Programmer's Guide to Common Lisp}, Deborah G. Tatar,
Digital Press, 1987.
\item{} {\it History of
Programming Languages}, edited by Richard Wexelblat, Academic Press,
1981.
\item{} {\it NIL -- A Perspective}, JonL White, MacSyma User's Conference,
1979.

\item{} {\it Common LISPcraft}, Robert Wilensky, W. W. Norton, 1986.
\endlist

∂01-Mar-89  1138	X3J13-mailer 	Section 1.6
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 1 Mar 89  11:38:01 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA02703; Wed, 1 Mar 89 11:35:58 PST
Message-Id: <8903011935.AA02703@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
	for x3j13@sail.stanford.edu; id AA02703; Wed, 1 Mar 89 11:35:58 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 1 Mar 89 07:23
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: Section 1.6

%%Implementation-defined Features

The following sections contain lists of implementation-dependent 
language characteristics.
For more
information about each of these implementation dependencies, see
Chapters 6 and 7 for the description of the {\word tool} being qualified.

\beginsubSection{Values}
%%\item{2.}
\beginlist
\item{1.}
An implementation determines the initial values of the {\word tools}
in Figure {\chapno--\the\capno}.

\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt boole-clr}&{\tt  boole-set}\cr
{\tt  boole-1 }& {\tt boole-2}\cr
{\tt  boole-c1}&{\tt  boole-c2}\cr
{\tt boole-and}&{\tt  boole-xor }\cr
{\tt boole-eqv}&{\tt boole-nand}\cr
{\tt  boole-nor }&{\tt  boole-orc1}\cr
{\tt boole-orc2}& \cr
& \cr
{\tt array-dimension-limit }&{\tt  array-rank-limit }\cr
{\tt  array-total-size-limit }&{\tt call-arguments-limit }\cr
{\tt multiple-values-limit}&{\tt lambda-parameters-limit }\cr
{\tt char-bits-limit }&{\tt  char-code-limit }\cr
  & \cr
@var[features] & {\tt internal-time-units-per-second} \cr
& \cr
{\tt most-positive-fixnum }&{\tt  most-negative-fixnum } \cr
{\tt most-positive-short-float }&{\tt  least-positive-short-float }\cr
{\tt most-positive-double-float }&{\tt least-positive-double-float }\cr
{\tt most-positive-long-float }&{\tt  least-positive-long-float }\cr
{\tt most-positive-single-float }&{\tt  least-positive-single-float }\cr
{\tt most-negative-short-float }&{\tt  least-negative-short-float }\cr 
{\tt most-negative-single-float }&{\tt  least-negative-single-float }\cr
{\tt most-negative-double-float }&{\tt  least-negative-double-float }\cr
{\tt most-negative-long-float }&{\tt  least-negative-long-float }\cr
{\tt short-float-negative-epsilon }&{\tt  single-float-negative-epsilon }\cr
{\tt double-float-negative-epsilon }&{\tt  long-float-negative-epsilon }\cr
 &  \cr
@var[load-verbose]  & @var[print-array] \cr
 @var[print-pretty] &@var[random-state] \cr
 @var[read-default-float-format] &  \cr
\noalign{\vskip -9pt}
}}
\caption{Implementation-defined values}
\endfig                 
      
%%\item{42.} 
\item{2.} The implementation determines the defaults for the
@Kwd[rehash-size] and 
@Kwd[rehash-threshold] 
arguments for 
{\function make-hash-table}.

%%\item{44.} 
\item{3.} The implementation determines the way in which a 
{\datatype sequence} is initialized if an @Kwd[initial-element] 
argument is not supplied. See {\function make-sequence}.
The implementation determines the way in which a 
{\datatype string} is initialized if an @Kwd[initial-element] 
argument is not supplied. See {\function make-string}.
Also, the implementation determines the way in which an
{\datatype array\/} is initialized if @Kwd[initial-element]\rm,
@Kwd[initial-contents]\rm, or @kwd[displaced-to]
arguments are not supplied. See {\function make-array\/}.

%%\item{58.} 
\item{4.} Valid values for the argument to
{\function char-bit} and {\function set-char-bit}
are implementation-dependent.

\endlist
\endsubSection%{Values}

\beginsubSection{Results}
\beginlist
\item{1.}
%%12.5.2 7
An implementation may return the result of the 
absolute value of a {\datatype complex}
number composed of {\datatype integer} 
real and imaginary parts as either a {\datatype floating}-point
number or an {\datatype integer}. See {\function abs}.

%%\item{7.}
\item{2.}
An implementation determines the result returned from 
{\function lisp-implementation-type},
{\function type-of},
 {\function 
lisp-implementation-version}, and {\function software-version}.

%%\item{18.} 
\item{3.} An implementation determines the result of {\function digit-char}
when more than one character object can encode the supplied weight in
the given radix.

%%\item{20.} 
\item{4.} An implementation may determine the consequences in 
{\function do} and
{\function do{\tt $*$}} when the index variable is changed within the iteration
loop.

%%\item{30.} 
\item{5.} The result of {\function
file-position} for a character file is implementation-dependent.

%%\item{34.} 
\item{6.} An implementation determines the order of elements in the results
of {\function intersection}, 
{\function set-difference}, and {\function
union} and derivatives of those functions.
Some element-processing aspects of sorting are implementation-dependent.
See {\function sort}.

%%\item{36.} 
\item{7.} Whether or not {\function length} 
or any sequence operation returns when given a circular
{\datatype list} is implementation-dependent.

%%\item{39.} 
\item{8.} The implementation determines the {\word type} of 
the result of {\function log} ({\datatype integer} or {\datatype
floating-point})
when its arguments are both {\datatype integers} and the result is a whole
number.
 
%%\item{41.} 
\item{9.} The implementation determines the result of {\function make-char}.

%%\item{46.} 
\item{10.} An implementation determines the result of 
{\tt (eq (symbol-name (make-symbol x)) x)}.
                                       
%%\item{47.} 
\item{11.} 
An implementation determines the {\word type} 
of the result of {\function
max} and {\function min} in the following cases.
\beginlist
\itemitem{a.}
If the arguments are a mixture of {\datatype rationals} and 
{\datatype floating-point}
numbers and the largest argument
is a {\datatype rational}.
\itemitem{b.} If the largest argument is a {\datatype floating-point}
number of a smaller format
than the largest format of any {\datatype floating}-point argument.
\endlist
In addition, if one or more of the arguments are equal, then any one
of them may be chosen as the value to return.
%%\item{62.} 
%\item{12.} {\function special-form-p} can return a non-@nil\ value,
%the identity of which is implementation-dependent.

%%\item{63.} 
\item{12.} If the argument to {\function sqrt} is an {\datatype integer},
the result may be either an {\datatype integer}
or a {\datatype float}ing-point number depending on the
implementation.  Also, if the argument to {\function sqrt} is a negative
{\datatype integer},
the result 
may be either a 
{\datatype complex} number with {\datatype integer} components or
a {\datatype complex} number with {\datatype floating}-point components.

%%\item{64.} 
\item{13.} If no characters in the argument to {\function string-trim},
{\function string-left-trim}, {\function string-right-trim}, 
{\function string-upcase}, {\function string-downcase}, and
{\function string-capitalize} need to be changed, then the implementation can
either return the argument itself or a copy of it.
This is true for all destructive
{\datatype sequence} functions.

%%\item{71.} 
\item{14.} When the arguments to
a mathematical {\word function} are 
all {\datatype rational} and the true mathematical result
is also (mathematically) rational, then unless otherwise noted
an implementation is free to return either an accurate result of
{\word type} {\datatype rational} 
or a {\datatype single-float} approximation.
If the arguments are all {\datatype rational} 
but the result cannot be expressed
as a {\datatype rational} number, then a {\datatype single-float} 
approximation is always returned.



\endlist
\endsubSection%{Results}


\beginsubSection{Data Representation and Typing}
\beginlist
%%\item{5.}
\item{1.}
An implementation determines the representation of a byte specifier.

%%\item{9.}
\item{2.}
An implementation determines the {\word type} of the {\word object} returned
from {\function coerce} when the result is specified to be a specialized
type.
%%\item{11.}
\item{3.}             
An implementation can define declaration specifiers other than the ones
given in the description of {\function declare}.


%%\item{27.} 
\item{4.} An implementation determines the format of the environment
argument to {\function evalhook} and 
the argument that comes to {\function defmacro} via \&environment; the
{\function defmacro} and 
{\function evalhook} environment arguments are not necessarily in the same
format.     
%%\item{75.} 
\item{5.} The existence of 
{\word types} that are not {\word subtypes} of {\datatype common}
is implementation-dependent.

\endlist
\endsubSection%{Data Representation and Typing}

\beginsubSection{Program and Control Structure}
\beginlist

%%\item{13.}
%\item{1.}
%An implementation 
%may or may not check for any dynamic {\word bindings}
%of the first argument to {\function defconstant} at the time 
%{\function defconstant} is executed.



%%\item{14.}
\item{1.}
An implementation determines the way that {\function defmacro}
actually installs a macro function.

%%\item{15.}
\item{2.}
An implementation determines the code generated by {\function defsetf}.


%%\item{16.}
\item{3.}
The following are implementation-dependent features of {\function defstruct}:
\beginlist
\itemitem{a.} The initial contents of a slot, when they have not been provided,
are specified by the implementation.
\itemitem{b.} The access functions may be declared {\function inline}.
\itemitem{c.} The incorrect use of access functions may or may not be checked
by an implementation.
\itemitem{d.} For included slots, an implementation may or may not check
{\word type} assignments.
\itemitem{e.} If the {\keyword :type} option is not supplied, the implementation
determines the representation of the {\datatype structure}. 
%%(see clean-up issue)
\endlist

%%\item{35.} 
\item{4.} The permissibility of non-standard {\word lambda-list}
keywords is implementation-dependent.

%%\item{40.} 
\item{5.} 
An implementation is free
to implement as a {\word special form} any {\word construct} 
described in this standard as a {\word macro},
if an equivalent {\word macro} definition is also provided.
See {\function macro-function}.

%%\item{60.} 
\item{6.} 
The exact expansion for any particular form given to {\function setf} 
may be implementation-dependent.

%%\item{76.} 
\item{7.} The internal representation of 
a backquoted {\word form} is implementation-dependent.

\endlist
\endsubSection%{Program and Control Structure}

\beginsubSection{Comparisons}
\beginlist
%%\item{6.}
\item{1.}
An implementation determines the way font information is compared in the
functions {\function char-equal, char-not-equal, char-lessp, char-greaterp,
char-not-greaterp}, and {\function char-not-lessp}. Where not
specified by this standard, the ordering of 
characters is implementation-dependent.
\endlist
\endsubSection%{Comparisons}




\beginsubSection{Numerical Calculations}
\beginlist
%%\item{8.} 
\item{1.} {\function minusp},
{\function eql},
{\function float-sign}, and 
{\function zerop}
are affected by the presence
of {\tt $-0.0$} in an implementation.

%%\item{24.} 
\item{2.} Whether or not two {\datatype numbers} or {\datatype characters} 
are {\function eq}
depends on the implementation.

%%\item{26.} 
\item{3.} Whether two {\datatype floating}-point 
numbers of different {\word types} are {\function eql} depends
on the implementation because it is possible for an implementation to
have less than four floating-point data types.

%%%\item{29.} 
%\item{4.} An implementation may use different algorithms
%for the cases of a {\datatype rational} second 
%argument and a {\datatype floating}-point
%second argument to {\function expt}.

%%\item{55.} 
\item{4.} Random number generation is implementation-dependent.


%%\item{70.} 
\item{5.} For the {\word operators} in Figure {\chapno--\the\capno},
an implementation may process the arguments in any manner consistent
with associative (and possibly commutative) rearrangement.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 
plus 1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt + }&{\tt * }&{\tt max }\cr
{\tt min }&{\tt =}&{\tt /=}\cr
{\tt < }&{\tt >}&{\tt <=}\cr
{\tt >= }&{\tt gcd}&{\tt lcm}\cr
{\tt logior}&{\tt logxor}&{\tt logand}\cr
{\tt logeqv}&{\tt lognand}&{\tt lognor}\cr
{\tt logandc1}&{\tt logandc2}&{\tt logorc1}\cr
{\tt logorc2}&{\tt boole}&\cr
\noalign{\vskip -9pt}
}}
\caption{Mathematically associative operators}
\endfig
Implementations may differ in 
which automatic coercions are applied because of differing
orders of argument processing. 

%%\item{72.} 
\item{6.} 
The precise definitions of {\datatype short-float},
{\datatype long-float}, {\datatype single-float}, and 
{\datatype double-float} are implementation-dependent.

\endlist
\endsubSection%{Numerical Calculations}


\beginsubSection{User Interface}
\beginlist
%%\item{.}
\item{1.}
An implementation determines the user interface for the read-eval-print loop
in the {\word
operators} and variables in Figure {\chapno--\the\capno}.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 
plus 1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt break }&{\tt check-type }&{\tt describe }\cr
{\tt disassemble }&{\tt inspect }&{\tt step }\cr
{\tt warn }&{\tt y-or-n-p }&{\tt yes-or-no-p }\cr
{\tt error }&{\tt cerror }&{\tt ccase }\cr
{\tt ccase }&{\tt ctypecase }&{\tt Anything that uses cerror }\cr
\noalign{\vskip -9pt}
}}
\caption{User interface operators and variables}
\endfig
\endlist
\endsubSection%{User Interface}


\beginsubSection{Input/Output}
\beginlist

%%\item{17.} 
\item{1.} An implementation determines whether an attempt by {\function   
delete-file} to delete a non-existent file is considered to be successful.

%%\item{19.} 
\item{2.} An implementation may define keywords to be used with
{\function directory}.

%%\item{31.} 
\item{3.} An implementation determines the precise actions of
{\function finish-output}, {\function clear-output}, and {\function
force-output}. 

%%\item{31a.} 
\item{4.} {\datatype Streams} 
may be implemented in an asynchronous or buffered manner.

%%\item{32.} 
\item{5.} {\function format} has the following implementation-defined
features:
\beginlist
%% CLean-up item on this
\itemitem{a.} {\tt @tilde C} prints a character in an implementation-dependent
abbreviated format.  

\itemitem{b.} The precise output for {\tt @tilde :{\char '100}C} depends 
on the implementation.
\itemitem{c.} When rounding up and rounding down would produce printed values
equidistant from the scaled value of the argument, then the implementation
is free to use either one.  
\itemitem{d.} For the {\tt @tilde \$} operation, if the magnitude of the argument is so large or small 
that more than 100 digits would have to
be printed, then an implementation is free, at its discretion, to print
the number using exponential notation.
\itemitem{e.} For the {\tt @tilde \$} operation, if 
the argument is a {\datatype rational} number, 
then it is coerced to be a {\datatype single-float}
or processed by any other method that has essentially the
same behavior. 
Only a finite number of digits may be printed.
\endlist
%%\item{37.} 
\item{6.} The means by which a text (character file) 
is distinguished from an object (binary) file is
implementation-dependent. 

%%\item{38.} 
\item{7.} The selection by {\function load} of a file type when there
is a choice is implementation-dependent.

%%\item{43.} 
\item{8.} The implementation determines the internal representation
of a {\datatype pathname}. See {\function make-pathname}.

%%\item{48.} 
\item{9.} The following aspects of {\function open}
are implementation-dependent:
\beginlist
\itemitem{a.} {\keyword :supersede} 
\itemitem{b.} An implementation is required to recognize all of 
the following {\keyword if-exists} keywords
and to do something reasonable in the context of the host operating
system:
{\keyword :error},
{\keyword :new-version},
{\keyword :rename},
{\keyword :rename-and-delete},
{\keyword :overwrite},
{\keyword :append},
{\keyword :supersede}, or
@false\rm.       

\itemitem{c.} If it is impossible for an implementation to handle some option
in a manner close to what is specified in this manual, an error may be
signalled.
\endlist                                             

%%\item{50.} 
\item{10.} {\function parse-namestring}
may or may not signal an error if
the representation of a {\datatype pathname} 
is surrounded on either side by
whitespace characters, depending on the implementation.
Whether or not {\function parse-namestring} supplies 
the
standard default device as the device component
of the resulting {\datatype pathname} depends on the implementation.

%%\item{51.} 
\item{11.} The {\datatype pathname} namestring
syntax is implementation-dependent.
The printed representation of a pathname
typically designates {\keyword :wild} by an asterisk; however, this is
implementation-dependent.    

%%\item{52.} 
\item{12.} A {\datatype character} name or a {\datatype pathname}
that is typed out
is acceptable as input in only the implementation which typed it.  
Which names for characters are chosen to print is
implementation-dependent, although standard names are
chosen over non-standard names. See {\function write}.
        
%%\item{53.} 
\item{13.} The printed representation of a
{\datatype random-state} object is implementation-dependent.

%%\item{54.} 
\item{14.} {\word Objects} which do not have a specific syntax
specified in this manual are printed in an implementation-dependent manner.  

%%\item{68.} 
\item{15.} The {\arg host} 
argument to {\function user-homedir-pathname}
defaults in an implementation-dependent manner.

%%\item{77.} 
\item{16.} Whether the following 
character names are supported is implementation-dependent:
@f[rubout]\rm, @f[page]\rm,
@f[tab]\rm,
@f[backspace]\rm, 
@f[return]\rm, and 
@f[linefeed]\rm.
%%\item{78.} 
\item{17.} Whether 
characters with non-zero {\arg bits} and {\arg font} attributes
syntax
descriptions are in the {\datatype readtable} is implementation-dependent.

\endlist
\endsubSection%{Input/Output}
                           

\beginsubSection{Compiling}
\beginlist
%%\item{10.}
\item{1.}
An implementation determines the following for {\function compile-file}:
\beginlist
\itemitem{a.} The contents of the file created by {\function compile-file}.
\itemitem{b.} The file 
specification (if one is not supplied)
for the file created by {\function compile-file}.
\endlist
%%\item{12.}
\item{2.}
An implementation's compiler can ignore declaration
specifiers except for {\tt declaration}, {\tt special}, and
{\tt notinline}.

%%\item{25.} 
\item{3.} An implementation may ``collapse'' constants or portions of constants
in code to be compiled if they appear to be {\function eq}
or {\function eql} and are {\function equal}.
See ``Compilation''.
%%\item{79.} 
\item{4.} The representation of the {\word object} produced by
the compiler, and the internals of the compiler
are implementation-dependent, except that {\function compile} produces
a {\datatype compiled-function}.

\endlist
\endsubSection%{Compiling}


\beginsubSection{Miscellaneous}
\beginlist
%%\item{4.}
\item{1.}
An implementation determines the specifics of the
debugger that {\function break} enters.

%%\item{74.} 
\item{2.} Although functions that manipulate {\datatype packages}
generally signal
name conflict errors before making any change to the package structure, an
implementation may {\function export} 
each of a given list of {\datatype symbols} separately.

%%\item{49.} 
\item{3.} The contents of the @f[system] package are determined by
the implementation.

%%\item{57.} 
\item{4.} The frequency of execution of test and key
functions for all sequence functions is implementation-dependent. 
The implementation of 
{\function search} may choose to search the {\datatype sequence} in any order.

%%\item{65.} 
\item{5.} The manner in which a 
hash code is computed by {\function sxhash}
is implementation-dependent. 

%% clean-up pending for this
%%\item{69.} 
\item{6.} The optional argument {\arg extension}
for {\function
vector-push-extend}
defaults to a ``reasonable'' implementation-dependent
value.

%%\item{73.} 
\item{7.} A {\datatype symbol's} property list may have defined components.
\endlist
\endsubSection%{Miscellaneous}



\beginsubSection{Programming Environment}
\beginlist
%%\item{22.} 
\item{1.} An implementation may or may not provide a resident editor.
See {\function ed}.

%%\item{23.} 
\item{2.} An implementation determines the means by which
function text is obtained when {\tt (ed {\it symbol})} is invoked.

%%\item{33.} 
\item{3.} An implementation determines the units used in representing
Internal Time.
See {\function get-internal-run-time}.

%%\item{56.} 
\item{4.} The information {\function room} prints is
implementation-dependent.  
%%\item{66.} 
\item{5.} The nature and
format of the information printed by {\function time} 
is implementation-dependent.  
           
%%\item{67.} 
\item{6.} The following are implementation dependencies of
tracing.
\beginlist
\itemitem{a.} {\function trace} and {\function untrace} may accept 
implementation-dependent argument formats.  
\itemitem{b.} The format of the {\function trace}
output is implementation-dependent.
\endlist        
\endlist        
\endsubSection%{Programming Environment}

∂01-Mar-89  1207	X3J13-mailer 	Section 2.1
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 1 Mar 89  12:06:27 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA06314; Wed, 1 Mar 89 12:04:26 PST
Message-Id: <8903012004.AA06314@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
	for x3j13@sail.stanford.edu; id AA06314; Wed, 1 Mar 89 12:04:26 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 1 Mar 89 07:24
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: Section 2.1

%% Introduction to Objects and Types

%% 2.0.0 4
%% 6.2.1 1
A {\word data type} (a {\word type}) 
is a (possibly infinite) set of
{\word objects}.  An {\word object} can belong to more than one
{\word type}. @Funref[typep] is used to determine
whether an {\word object} is of a given {\word type},
a set membership test, while {\function subtypep}
is a subset test.
@Funref[type-of] returns a {\word type}
to which an {\word object} belongs.


%% 9.1.0 1
Type declarations can be embedded in executable
code using {\function declare}.
Global type declarations are established by {\function proclaim}.
%% 9.3.0 1
%The special form {\function the} is used to declare
%the {\word type} of the value of an 
%unnamed {\word form}.
%The form {\tt (the type form)} means
%that the value of {\tt form} 
%is declared to be of type {\tt type}.
%% 1.1.0 4
%% 9.0.0 3
%All type declarations are optional
%and correct type declarations do not affect the meaning
%of a correct program.  
%All type declarations are of an advisory nature, and may be used
%by the @xlisp\ system in performing error checking
%or producing more efficient compiled code.
%% 9.0.0 4
The consequences are undefined if a program violates a
type declaration (such as a {\function type} declaration), 
but an implementation is
not required to detect such errors.
%% 9.2.0 1

%% 2.0.0 1
Data {\word objects}, not variables, are {\word typed}. 
Normally, any variable 
can have any @xlisp\ {\word object} as its value.
It is possible to make an explicit 
type declaration that a variable will
take on one of only a limited set of values. 
%% 2.0.0 5
@clisp\ {\word types} are arranged in a directed acyclic graph. 
%Therefore,
%it is possible for an {\word object} to belong to more than one
%{\word type}.                                           
%% 2.12.0 1
%%% 19.1.0 1
%{\word Structures} created by @Macref[defstruct]
%are instances of user-defined {\word types}.

%%% Beginning of CLOS stuff
%\beginSection{Introduction}
%
The \CLOS\ is based on
{\word generic functions}, multiple inheritance, declarative {\word method}
combination, and a meta-object protocol.
%
%The first two chapters of this specification present a description of
%the standard Programmer Interface for the \CLOS.  The first chapter
%contains a description of the concepts of the \CLOS, and the second
%contains a description of the functions and macros in the \CLOS\
%Programmer Interface.  The chapter ``The \CLOS\ Meta-Object
%Protocol'' describes how the \CLOS\ can be customized.
%
The fundamental {\word objects} of the \CLOS\ 
are {\word classes}, {\word instances},
{\word generic functions}, and {\word methods}. 

A {\bit class\/} object determines the structure and behavior of a set
of other {\word objects}, which are called its {\bit instances}. 
Every {\word object} is an {\bit
instance\/} of a {\word class}.  The 
{\word class} of an {\word object} determines the set of
operations that can be performed on the {\word object}.
See ``Generic Functions and Methods''.
%%\endSection%{Introduction}

∂01-Mar-89  1232	X3J13-mailer 	Section 1.2
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 1 Mar 89  12:32:32 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA09839; Wed, 1 Mar 89 12:30:26 PST
Message-Id: <8903012030.AA09839@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
	for x3j13@sail.stanford.edu; id AA09839; Wed, 1 Mar 89 12:30:26 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 1 Mar 89 07:21
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: Section 1.2

%%Organization of the Document

This document is divided into seven chapters:

\beginlist                         
\item{\bull} This introduction.
\item{\bull} A description of @clisp\ types and objects.
\item{\bull} A description of the syntax of @clisp\ objects.
\item{\bull} The @clisp\ evaluation and compilation processes.
\item{\bull} A description of the @clisp\ interfaces to
its environment and a description of the condition
system.
\item{\bull} A catalog of @clisp\ symbols (divided into two chapters).
\endlist

∂01-Mar-89  1232	X3J13-mailer 	Section 1.1
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 1 Mar 89  12:32:28 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA09717; Wed, 1 Mar 89 12:30:00 PST
Message-Id: <8903012030.AA09717@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
	for x3j13@sail.stanford.edu; id AA09717; Wed, 1 Mar 89 12:30:00 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 1 Mar 89 07:21
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: Section 1.1

%%Scope, Purpose, and History
\beginsubSection{Scope and Purpose}
The standard specification set forth in this document
is designed to promote the portability of @clisp\ programs
among a variety of data-processing systems. It is intended for use
by implementors and knowledgeable programmers, and is not a tutorial.
This standard is intended to be a language specification
rather than an implementation specification.
An
implementation is free to achieve the semantics
specified in this standard by any means. The @clisp\ definitions
in Chapters 6 and 7 need not be reflected directly in the implementation.
\endsubSection%{Scope and Purpose}
\beginsubSection{History}

Lisp is the second oldest high-level programming language still in current use.
(The oldest high-level programming language still in widespread use
is Fortran.)
@clisp\ is a joint-venture language stemming from several
research and development projects in the late 1970's.  Its
roots reveal why some of the features of the language were
added. From a short look at these roots, it can also be seen
how these features influence the architectural requirements
for a high-quality implementation.
 
 
From the mid-1960's through much of the 1970's,  DEC's PDP10 computer 
was the mainstay of Lisp work at MIT and Stanford's AI and Computer 
Science Labs, at BBN in Cambridge, at CMU, and at selected other sites.
Designed in the early 
1960's, the PDP10  had the unique advantage of being influenced by 
John McCarthy, the  ``Grandfather of Lisp'', and as a result has
half-word instructions suitable for {\word car} and {\word cdr} 
instructions, and
stack instructions to facilitate recursive programming. 
But the limitations of this old machine were painfully 
evident by 1973, two of which were
the high cost to support a single researcher,
and the small address space available ($2↑{18}$ = 262,144 words).
 
To alleviate the latter problem, BBN Lisp (developed at Bolt, Bernak, 
\& Newman in Cambridge, and later, with Xerox's 
participation,  called Interlisp)
added a ``black hole'' feature somewhat akin to ``paging''
on a function basis rather than on a page-boundary basis. MacLisp 
(developed at the MIT AI Lab and Laboratory for Computer Science) 
added an ``autoload'' feature, whereby only the functions actually used 
would be loaded in to ``core''.  Large applications such as the 
symbolic algebra system MACSYMA and the Interlisp programing development 
environment were driving forces for larger address space capabilities.
 
In the early 1970's, at Xerox's Palo Alto Research Center, L. Peter Deutch 
conceived of a personal workstation with an architecture
tailored to the needs of Lisp. This architecture would allow
a machine to be affordable to an 
individual researcher and to have sufficient power to run large Lisp 
applications.  
Soon thereafter, Richard Greenblatt began work
on a similar design at MIT's AI Laboratory.
Eventually, a dialect of Interlisp known as Interlisp-D became available
on 
the ``D-series'' machines manufactured by Xerox, and an upward-compatible
extension of MacLisp became available on the early MIT ``Lisp'' machines.
Both of these efforts culminated in commercial Lisp machines that were
seen in laboratory prototype at about the time of the 1980 Lisp Conference 
at Stanford, and were marketable by 1981.
 
In another direction, in the late 1970's the MacSyma group at MIT
began 
a project called New Implementation of Lisp (NIL). In additon
to capitalizing on the large address space and other hardware 
capabilities of the VAX, one of the stated goals of NIL was to fix many
of the historic, but annoying, little problems of the Lisp
language while still retaining an essentially upward-compatible
outlook. At about the same time, a research group 
at Stanford University and Lawrence Livermore National Laboratory
began the design of a Lisp to run on the supercomputer,
S-1. Recognizing the similarity of 
their goals to those of the MIT NIL project, the S-1 group
began to collaborate with the NIL group.
 
In a third direction, around 1980, Scott Fahlman and others at CMU 
began work on a Lisp to run on the SPICE workstation.
The SPICE machine had a much weaker microcode capability
than the MIT Lisp Machine, so the goal was to emulate as much of the
MIT design as was feasible.
 
After a DARPA-sponsored meeting on the future of Lisp in April 1981,
representatives 
of several of the post-MacLisp efforts (Gabriel, Steele, White, and Fahlman)
decided to join forces by 
directing their efforts towards a common, portable dialect of Lisp.  
Further design sessions were held at CMU in June 1981. Later that 
fall, Symbolics Corporation representatives began assisting in
designing the new dialect.

 
After the name was chosen (@clisp) the task then turned to a
choice of how much of the design could be retained from the Lisp 
machines, and how much seemed to pre-suppose special purpose hardware.  Also
there was a task of sorting out which features of conventional
languages for conventional hardware architectures, like compile-time 
typing, could be integrated into the new language without damaging 
its essential Lisp character.  The theorists of each
camp allowed some deviations from what they considered theoretically
best, and the result
was a language suitable for general purpose hardware, but with certain
particular implementational problems to be met.
@maclisp, @lmlisp, @scheme, @interlisp, @slisp, @s1lisp, @newlisp,
@stdlisp, and @psl\ 
were each considered during the design of
@clisp\rm, and the most useful features of each were incorporated.
{\it Common LISP the Language},  
was written by members of the informal design group. 
 
The semantics in {\it Common LISP the Language} were intentionally
underspecified in 
places where it was felt that a tight specification would
unduly constrain @clisp\ research and use. 
However, industrial use of @clisp\
mandates implementations to produce the same results given the same arguments
in order that code can be ported between implementations. 
In addition, @clisp\ users recognized the need to agree on standard 
object-oriented and condition systems, iteration facilities, and
a way to handle large character sets.
Therefore, a new language specification, this document, was created by
the X3J13 committee.
\endsubSection%{History}

∂01-Mar-89  1234	X3J13-mailer 	Section 1.4
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 1 Mar 89  12:34:33 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA09935; Wed, 1 Mar 89 12:32:23 PST
Message-Id: <8903012032.AA09935@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
	for x3j13@sail.stanford.edu; id AA09935; Wed, 1 Mar 89 12:32:23 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 1 Mar 89 07:22
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: Section 1.4

%%Definitions

This section contains notational conventions used in this manual.

The font key to be used in Chapters 1-5
is as follows:
\beginlist
                                            
\itemitem{\datatype data-type} 

Denotes
@clisp\ {\word data types}.

\itemitem{\word defined word} 

Denotes the words whose
definitions appear in the ``Glossary''.

\itemitem{\function tools} 

Denotes {\word tools}.

\itemitem{\keyword keywords} 

Denotes {\word keywords}.
\endlist
                                                    

%% 1.2.1 1
All numbers in this book are in decimal notation
unless otherwise noted.

%% 1.2.5 9
The dot appearing in the expression
@f[(sample-macro @i[var] {\char '056} @i[body])]
means that @f[body] stands
for a list of {\word forms}, 
not just a single {\word form}, at the end of a list.  

The following notations are used in this document:
\beginlist
\itemitem{\word @EV\rm} 

Indicates {\word evaluation}.
For example:

@Lisp
 (+ 4 5) @EV 9
@Endlisp
means that the result of {\word evaluating} the code @f[(+ 4 5)] is @f[9]\rm.
                                                                 
%% 1.2.3 3
\itemitem{\word @EQ} 

Indicates code 
equivalence.
For example:

@Lisp
 (gcd x (gcd y z)) @EQ (gcd (gcd x y) z)
@Endlisp
means that the results and observable 
{\word side-effects} of {\word evaluating }
the {\word form}
@f[(gcd x (gcd y z))] are always the same as the results
and observable {\word side-effects} of
@f[(gcd (gcd x y) z)] for any 
@f[x]\rm, @f[y]\rm, and @f[z]\rm.
                      

%% 1.2.5 4
\itemitem{@t} 

The canonical truth value.
Any {\word object} other than @false\ is construed to be Boolean
``not false,'' that is, ``true.''  The {\datatype symbol} @true\ is 
used to mean ``true'' when no other value is more appropriate.
When a {\word function} is said to ``return @i[true]\rm'' or to ``be @i[true]\rm''
in some circumstance, this means that it returns some value other
than @false\rm, but not necessarily @true\rm.

\itemitem{@nil} 

Represents the empty {\datatype list} and
the ``false'' value for Boolean tests.
The {\datatype symbol} @f[nil] evaluates to
itself, so @f['nil] and @f[nil] denote the same {\word object} 
in terms of evaluation.
The former syntax is used to emphasize that the result is 
a {\datatype symbol},
while the latter is used to emphasize that the result is
a boolean value. @f['()] 
is used to denote the
empty {\datatype list} 
in terms of evaluation. It is used in a quoted structure
or a program structure. 

For example:
 
\screen!
 (print ())                          ;avoided
 '(nil nil)                          ;list of symbols
 '(()())                             ;list of empty lists
 (defun three () 3)                  ;Emphasize empty parameter list.
 (append '() '()) @EV ()               ;Emphasize use of empty lists
 (not @false) @EV @true                       ;Emphasize use as Boolean "false"
 (get '@nil 'color)                   ;Emphasize use as a symbol
\endscreen!

When a function is said to ``return @i[false]\rm'' or to ``be @i[false]\rm''
in some circumstance, this means that it returns @false\rm.

\endlist
           

∂01-Mar-89  1240	X3J13-mailer 	Section 5.3
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 1 Mar 89  12:40:11 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA10373; Wed, 1 Mar 89 12:38:09 PST
Message-Id: <8903012038.AA10373@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
	for x3j13@sail.stanford.edu; id AA10373; Wed, 1 Mar 89 12:38:09 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 1 Mar 89 07:26
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: Section 5.3

%% Interface with the Programming Environment

\beginSubsection{Top level loop}
%% 20.2.0 1
The {\function read}-{\function eval}-{\function print} loop 
is the highest level of control and consists of an endless
loop that reads an expression, evaluates it, and prints the
results.  The parts of the
{\function read}-{\function eval}-{\function print} loop are individually
referred to as the reader, the evaluator, and the printer.

%% 20.2.0 2
The precise nature of the {\function read}-{\function eval}-{\function print}
loop 
is not rigorously specified; thus the user interface is
implementation-defined.

%% 20.2.0 3
The {\function read}-{\function eval}-{\function print} loop 
traps all {\function throws} and recovers from them.
It prints all values resulting from the evaluation of a 
{\word form}.

%% 20.2.0 4
The following variables are maintained by the 
{\function read}-{\function eval}-{\function print} loop.

{\tt +, ++, +++, *, **, ***, /, //, ///, -}.

See Chapter 6 for the meanings of these variables. 

\endSubsection%{Top level loop}


\beginSubsection{Environment inquiry}
%% 25.4.0 1
Environment inquiry {\word tools} provide information about the
system on which a @clisp\ program is being executed.
These {\word tools} 
aid in querying the hardware and software configuration, and
in debugging.

Figure {\chapno--\the\capno} lists the 
{\word tools} that are applicable to configuration inquiry.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt  @var[features] } & {\tt long-site-name } & {\tt room } \cr
{\tt  identity } & {\tt  machine-instance } & {\tt  short-site-name } \cr
{\tt  lisp-implementation-type } & {\tt machine-type } & {\tt software-type }
\cr
{\tt  lisp-implementation-version} & {\tt  machine-version } & {\tt
software-version } \cr
\noalign{\vskip -9pt} }} 
\caption{Configuration inquiry tools}
\endfig

Figure {\chapno--\the\capno} lists the 
{\word tools} that are applicable to debugging.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt  apropos } & {\tt  dribble } & {\tt step } \cr
{\tt apropos-list  } & {\tt ed }  & {\tt  trace } \cr
{\tt  describe } & {\tt inspect }& {\tt  untrace } \cr
{\tt documentation } & & \cr
\noalign{\vskip -9pt} }} 
\caption{Debugging tools}
\endfig

\endSubsection%{Environment inquiry}

\beginsubsubsection{Time}
%% 25.4.1 1
Time is represented in three different ways in @clisp\rm:
Decoded Time, Universal Time, and Internal Time.
The first two representations
are used primarily to represent calendar time, and are
precise only to one second.
Internal Time is used primarily to represent measurements of computer
time (such as run time) and is precise to some implementation-dependent
fraction of a second, as specified by @Conref[internal-time-units-per-second]\rm.
Decoded Time format is used only for absolute time indications.
Universal Time and Internal Time formats are used for both absolute
and relative times.
\beginlist
\itemitem{\bf Decoded time}

%% 25.4.1 2
Decoded Time format represents calendar time as a number of components:

%% 25.4.1 3
\beginlist
\itemitem{\bf Second} 

An {\datatype integer} between 0 and 59, inclusive.

%% 25.4.1 4
\itemitem{\bf Minute} 

An {\datatype integer} between 0 and 59, inclusive.

%% 25.4.1 5
\itemitem{\bf Hour} 

An {\datatype integer} between 0 and 23, inclusive.

%% 25.4.1 6
\itemitem{\bf Date} 

An {\datatype integer} between 1 and 31, inclusive (the upper limit actually
depends on the month and year, of course).

%% 25.4.1 7
\itemitem{\bf Month} 

An {\datatype integer} between 1 and 12, inclusive; 1 means January,
12 means December.

%% 25.4.1 8
\itemitem{\bf Year} 

An {\datatype integer} indicating the year A.D.  However, if this 
{\datatype integer}
is between 0 and 99, the ``obvious'' year is used; more precisely,
that year is assumed that is equal to the 
{\datatype integer} modulo 100 and
within fifty years of the current year (inclusive backwards
and exclusive forwards).  
Thus, in the year 1978, year 28 is 1928
but year 27 is 2027.  (Functions that return time in this format always return
a full year number.) 

%% 25.4.1 10
\itemitem{\bf Day-of-week} 

An {\datatype integer} between 0 and 6, inclusive;
0 means Monday, 1 means Tuesday, and so on; 6 means Sunday.
                      
%% 25.4.1 11
\itemitem{\bf Daylight-saving-time-p} 

A flag that, if not @false\rm, indicates that
daylight saving time is in effect.
 
%% 25.4.1 12
\itemitem{\bf Time-zone} 

%% should be a clean-up item about this
An {\datatype integer} specified as the number of hours west of GMT
(Greenwich Mean Time).  For example, in Massachusetts the time zone is 5,
and in California it is 8.  Any adjustment for daylight saving time is
separate from this.
\endlist
\itemitem{\bf Universal time}

%% 25.4.1 13
Universal Time represents time as a single non-negative {\datatype integer}.
For relative time
purposes, this is a number of seconds.  For absolute time, this is the
number of seconds since midnight, January 1, 1900 GMT.  Thus the time 1
is 00:00:01 (that is, 12:00:01 a.m.) on January 1, 1900 GMT.
Similarly, the time 2398291201 corresponds to time 00:00:01 on January 1,
1976 GMT.
Recall that the year 1900 was not a leap year; for the purposes of
@clisp\rm, a year is a leap year if and only if its number is divisible by 4, except
that years divisible by 100 are not leap years, except that years
divisible by 400 are leap years.  Therefore the year 2000 will
be a leap year.
(Note that the ``leap seconds'' that
are sporadically inserted by the world's official timekeepers as an additional
correction are ignored; @clisp\ assumes that every day is exactly 86400
seconds long.)
Because the @clisp\ Universal Time representation uses only
non-negative integers, times before the base time of midnight,
January 1, 1900 GMT cannot be processed by @clisp\rm.
\itemitem{\bf Internal time}

%% 25.4.1 14
Internal Time also represents time as a single {\datatype integer},
in terms of an implementation-dependent unit.
Relative time is measured as a number of these units.
Absolute time is relative to an arbitrary time base.
\endlist

Figure {\chapno--\the\capno} lists the 
{\word tools} that are applicable to time.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt time }&{\tt  get-decoded-time }\cr
{\tt  get-universal-time }& {\tt decode-universal-time }\cr
{\tt  encode-universal-time } & {\tt internal-time-units-per-second } \cr
{\tt get-internal-run-time }&{\tt  get-internal-real-time }\cr
{\tt  sleep } & \cr
\noalign{\vskip -9pt} }} 
\caption{Time tools}
\endfig

\endsubsubsection%{Time}

∂01-Mar-89  1243	X3J13-mailer 	Section 5.4
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 1 Mar 89  12:43:35 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA10362; Wed, 1 Mar 89 12:41:24 PST
Message-Id: <8903012041.AA10362@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
	for x3j13@sail.stanford.edu; id AA10362; Wed, 1 Mar 89 12:41:24 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 1 Mar 89 07:27
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: Section 5.4

%% Generalized Reference

When it is stated that an argument to a {\word function} or 
{\word macro} must be 
a generalized reference, this means that the argument must follow the
rules specified in this section. The definition for generalized reference
is given in terms of {\function setf},
which performs access and update operations within the
same {\word form}. 
Figure {\chapno--\the\capno} contains examples of the use of {\function setf}.
Note that the values returned by evaluating the {\word forms} in column two 
are not necessarily the same as those obtained by evaluating the {\word
forms}
in column three.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 
1fil&#\hfil\tabskip \dimen0 plus 1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
\hfil\bf Access function & Update function & Update using {\function setf} \cr
\noalign{\vskip 2pt\hrule\vskip 2pt}
{\tt x }&{\tt  (setq x datum) }&{\tt  (setf x datum) }\cr
{\tt (car x) }&{\tt  (rplaca x datum) }&{\tt  (setf (car x) datum) }\cr
{\tt (symbol-value x) }&{\tt  (set x datum) }&{\tt  (setf (symbol-value x) datum) }\cr
\noalign{\vskip -9pt}
}}
\caption{Examples of setf}
\endfig


Figure {\chapno--\the\capno} lists the {\word operators} 
that are applicable to generalized reference. Some manipulate generalized
references and some manipulate {\function setf} methods.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 
1fil&#\hfil\tabskip \dimen0 plus 1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt setf }&{\tt  psetf }&{\tt  shiftf }\cr
{\tt rotatf }&{\tt  getf }&{\tt  remf }\cr
{\tt incf }&{\tt  decf }&{\tt  push}\cr
{\tt pop }&{\tt  assert }&{\tt  ctypecase }\cr
{\tt ccase} &{\tt  define-modify-macro }&{\tt  defsetf }\cr
{\tt define-setf-method }&{\tt  get-setf-method }&{\tt  get-setf-method-multiple-value }\cr
\noalign{\vskip -9pt}
}}
\caption{Generalized reference operators}
\endfig

%% 7.2.0 29
%% 7.2.0 30
These {\word operators} must guarantee that
subforms of generalized references are
evaluated 
exactly as many times as they appear in the source program, and
they are evaluated
in exactly the same order as they appear in the source
program 
\issue{PUSH-EVALUATION-ORDER}
(left to right)
whenever possible. The left-to-right rule does not
remove the obligation on writers of {\word macros} and 
users of {\function define-setf-method}  
to ensure
left-to-right order, however. 
\endissue{PUSH-EVALUATION-ORDER}

\issue{PUSH-EVALUATION-ORDER}
\beginlist
\itemitem{1.}
The evaluation ordering of subforms within a generalized reference
is determined by the order specified by the second value returned by
{\function get-setf-method}. 
For all predefined generalized references ({\function getf}, {\function ldb}),
this order of evaluation is exactly left-to-right. When a generalized
reference is derived from a macro expansion, this rule is applied after the
macro is expanded to find the appropriate generalized reference. 

If the user writes a {\function defmacro} or
{\function define-setf-method} 
that does not preserve order, the order specified in the
user's code holds. For example, given 

@lisp
 (defmacro wrong-order (x y) `(getf ,y ,x))
@endlisp

 then 

@lisp
 (push value (wrong-order place1 place2))
@endlisp

will evaluate {\tt place2} first and then {\tt place1} 
because that is the order they
are evaluated in the macro expansion.
 
\itemitem{2.}
For the {\word macros} 
that manipulate generalized references ({\function push},
{\function pushnew}, {\function getf\/}, {\function remf\/}, 
{\function incf\/}, {\function decf\/}, {\function shiftf\/}, {\function rotatef\/}, 
{\function psetf\/}, {\function setf\/}, {\function pop}, and those 
defined by {\function define-modify-macro}) the subforms of the 
macro call are evaluated exactly once
in left-to-right order, with the subforms of the generalized references
evaluated in the order specified in (1).

{\function push}, {\function pushnew}, {\function getf\/}, {\function remf\/}, 
{\function incf\/}, {\function decf}, {\function shiftf\/}, {\function rotatef\/}, 
{\function psetf\/}, {\function pop} evaluate all
subforms before modifying any of the generalized reference locations. 
{\function setf\/} (in
the case when {\function setf\/} has more than two arguments) 
performs its operation
on each pair in sequence, i.e., in 

@lisp
 (setf place1 value1 place2 value2 ...)
@endlisp
the subforms of {\tt place1} and {\tt value1} are evaluated, the location
specified by 
{\tt place1} is modified to contain the value returned by 
{\tt value1}, and
then the rest of the {\function setf\/} form is processed in a like manner.

\itemitem{3.}
For {\function check-type}, {\function ctypecase}, and 
{\function ccase}, subforms of the generalized
reference are evaluated once as in (1), but may be evaluated again if the
type check fails in the case of {\function check-type} 
or none of the cases hold in
{\function ctypecase} and {\function ccase}.

\itemitem{4.}
For {\function assert}, the order of evaluation of the generalized 
references is not specified.  
\endlist
Rules 2, 3 and 4 cover all macros defined in @clisp\ that manupulate
generalized references.

@lisp
 (let ((ref2 (list '())))
  (push (progn (princ "1") 'ref-1)
        (car (progn (princ "2") ref2)))) @EV "12"
@endlisp
@lisp
 (let (x)
    (push (setq x (list 'a))
         (car (setq x (list 'b))))
     x) @EV (((a) . b))
@endlisp

 {\function push} first evalutes {\tt (setq x (list 'a)) @EV\ (a)},
 then evaluates {\tt (setq x (list 'b)) @EV\ (b)},
 then modifies the {\word car} of this latest value to be {\tt ((a) . b)}.


\endissue{PUSH-EVALUATION-ORDER}
%% 7.2.0 31
For example, in 

{\tt (setf {\arg reference} {\arg value})}

{\arg value}
must be evaluated after all the subforms of {\arg reference} because
{\arg value} appears to the right of them.

%% 7.2.0 32
The expansion of these {\word operators} must consist of code that follows these
rules or has the same effect as such code.  This is accomplished by
introducing temporary variables bound to the 
\issue{PUSH-EVALUATION-ORDER}
subforms of the macro call.
\endissue{PUSH-EVALUATION-ORDER}
As an optimization in the implementation,
temporary variables may be eliminated whenever it
can be proven that removing them has no effect on the semantics of the program.
For example, a constant need never be saved in a temporary variable.
A variable or any {\word form} that does not have side effects need not be
saved in a temporary variable if it can be proven that its value will
not change within the scope of the generalized reference.

%% 7.2.0 57
A {\function setf\/} method may be derived from any
generalized reference.
A {\function setf\/} method 
describes how to store into that generalized reference and which subforms of
the macro call are evaluated.

%% 7.2.0 59
Given knowledge of the subforms of the macro call,
it is possible to avoid evaluating 
them multiple times or in the wrong
order.  A {\function setf\/} 
method for a given access form can be expressed as
five values:

%% 7.2.0 60
\beginlist
%% 7.2.0 64
\itemitem{\bf List of temporary variables}

The temporary variables 
will be bound to the {\word values} of
the value forms sequentially as if by @Specref[let*]\rm.
     
\itemitem{\bf List of value forms}

The values of the value forms (these are subforms of the access form)
are bound to the temporary variables.

%% 7.2.0 61
%% 7.2.0 65
\itemitem{\bf List of store variables}

The store variables (these are temporary variables) 
are to be bound to the values of the generalized reference form,
that is, the values to be
stored into the variable.  

%% 7.2.0 62
\itemitem{\bf Storing form}

The storing form modifies the value of the
generalized reference and guarantees to return the value of the
store variable as
its value; these are the correct values for {\function setf\/} to
return.  
The storing form may contain references to the temporary and store variables.

%% 7.2.0 63
\itemitem{\bf Accessing form}

The accessing form returns the value of the
generalized reference.
It may contain references to the temporary variables.
\endlist

%% 7.2.0 66
The value returned by the accessing form is
affected by execution of the storing form, but either of these
forms may be evaluated any number of times.


%% 7.2.0 67
The temporary variables and the store variables are generated names,
as if by @Funref[gensym] or @Funref[gentemp]\rm.

It is possible
to do more than one {\function setf\/} in parallel via
{\function psetf\/}, {\function shiftf\/}, and {\function rotatef\/}.  
Computation
of the {\function setf\/} 
method must always create new variable names; it may not return
the same ones every time.

Examples of the contents of the constituents of {\function setf\/} methods
follow.
%% 7.2.0 69
For a variable {\arg x}:

\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt ()               }&; list of temporary variables \cr
{\tt ()               }&; list of value forms \cr
{\tt (g0001)          }&; list of store variables \cr
{\tt (setq {\arg x} g0001)   }&; storing form \cr
{\arg x                }&; accessing form \cr
\noalign{\vskip -9pt}
}}
\caption{Examples of setf methods - 1}
\endfig

%% 7.2.0 70
For {\tt (car {\arg exp})}:

\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt (g0002)                            }&; list of temporary variables \cr
{\tt ({\arg exp})                             }&; list of value forms \cr
{\tt (g0003)                            }&; list of store variables \cr
{\tt (progn (rplaca g0002 g0003) g0003) }& ; storing form \cr
{\tt (car g0002)                        }&; accessing form \cr
\noalign{\vskip -9pt}
}}
\caption{Examples of setf methods - 2}
\endfig

%% 7.2.0 71
For {\tt (subseq {\arg seq s e})}:

\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt (g0004 g0005 g0006)                 }&; list of temporary variables \cr
{\tt ({\arg seq s e})                     }&       ; list of value forms \cr
{\tt (g0007)                            }&  ; list of store variables \cr
{\tt (progn (replace g0004 g0007 :start1 g0005 :end1 g0006) }& \cr
{\tt g0007) }& ; storing form \cr
{\tt (subseq g0004 g0005 g0006)         }&{\tt  ; accessing form} \cr

\noalign{\vskip -9pt}
}}
\caption{Examples of setf methods - 3}
\endfig

∂01-Mar-89  1305	X3J13-mailer 	Section 1.7
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 1 Mar 89  13:04:43 PST
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Wed, 1 Mar 89 16:00:20 EST
Received: from OCCAM.THINK.COM by sauron.think.com; Wed, 1 Mar 89 15:58:25 EST
Date: Wed, 1 Mar 89 16:01 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Section 1.7
To: chapman%aitg.DEC@decwrl.dec.com
Cc: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
In-Reply-To: <8903011907.AA00298@decwrl.dec.com>
Message-Id: <19890301210123.2.BARMAR@OCCAM.THINK.COM>

    Date: 1 Mar 89 07:23
    From: chapman%aitg.DEC@decwrl.dec.com

    A language extension is
    any implementation-supplied {\word tool} that isn't explicitly defined
    in this standard. 

I don't like this definition.  I suggest:
    
    A language extension is any documented implementation-defined behavior
    of a tool defined in this standard that varies from the behavior
    described in this standard; or a documented consequence in a situation
    that the standard defines as undefined, unspecified, or extendable by
    the implementation.

This accomplishes several things:

- It restricts the definition to tools described in the standard.
Implementations are expected to provide their own tools in their own
packages, and I don't think these are considered extensions (this would
require an implementation to litter its documentation with "this is an
extension to Common Lisp" on nearly every page).

- It only talks about "behavior".  Because of a cleanup issue voted on
in Hawaii, we already have specified that implementations are not
permitted to add tools with names in the standard-defined packages.
Because I don't think we want to consider tools in other packages as
extensions, the only thing left is the behavior of standard-defined
tools.

- It only refers to "documented" behavior.  If the implementation varies
from the standard in an undocumented way it is a bug, not an extension.
And if the situation has an undocumented consequence in an undefined,
unspecified, or extendable situation, it is not an extension, it is just
an accident of the implementation.

                                                barmar

∂01-Mar-89  1257	X3J13-mailer 	cs proposal and straw vote
Received: from multimax.encore.com by SAIL.Stanford.EDU with TCP; 1 Mar 89  12:53:49 PST
Received: from mist.encore.COM by multimax.encore.com with SMTP (5.61/25-eef)
	id AA20108; Wed, 1 Mar 89 15:51:57 -0500
Received: from localhost by mist. (4.0/SMI-4.0)
	id AA11442; Wed, 1 Mar 89 15:50:01 EST
Message-Id: <8903012050.AA11442@mist.>
To: baggins@ibm.com
Cc: x3j13@sail.stanford.edu
Subject: cs proposal and straw vote
Date: Wed, 01 Mar 89 15:49:59 EST
From: Dan L. Pierson <pierson@mist.encore.com>

General comments first.

I find the layout of the proposal, mainly Appendix A, confusing to the
point of uselessness.  As I understand it, chapters 1 and 2 are
intended to be a general overview of the proposal, but the detailed
changes in Appendix A are what we are effectively voting on.
Unfortunately, I can't understand Appendix A without spending a long
time destroying a copy of CLtL per draft.  All of the other committees
(and X3J13 as a whole) have accepted that we are writing a new
document, not rewriting Guy's book.  Why do you insist on only doing
the later?

Before the Hawaii meeting, I was willing to reluctantly ignore all of
the above and just trust the Character Committee to see that Appendix
A accurately reflected the contents of chapters 1 and 2.  The
combination of the revelation of deep disagreements within the
committee, and my own attempts to answer some questions by refering to
Appendix A have forced me to change my mind.  I find that I cannot
understand the proposal as presented and thus cannot vote for the
contents of Appendix A.  The straw ballot that follows represents my
willingness to vote for the specific issues as described in chapters 1
and 2 of the proposal provided that such a vote does not require
acceptance of the specific wording of Appendix A.

As an example of the above problems.  I was unable to find anywhere in
the latest draft either the data types of character labels and
registry names or the predicates to be used to compare them.  Your
replies to comments on the January draft state that these are symbols,
which seems correct, but the proposal does not appear to specify this.

Character Registries:

While the idea of character registries doesn't sound bad in principle,
I'm still not convinced that tying the first Common Lisp standard to
the output of an ISO committee which has not been (and may never be)
formed is wise.  If nothing else, this approach would appear to
guarantee a period of major incompatibility for the users of any
Common Lisp implementation which provided its own set of character
registries in advance of an ISO standard.  

By the way, I find the support of the ISO Prolog committee, which
seems to be being ignored by all major US and many international
Prolog implementors, rather meaningless.  If you could get support from
a major, effective ISO language committee or two I might be convinced.

Moon is correct that it is (barely) possible to enumerate all the
characters in a registry without additional functionality.  Never the
less, the method he proposes is far from desirable.  Since I believe
that adding non-enumerable data types to Common Lisp is a bad thing, I
sould be much happier if a registry iterator were added.  The following
would suffice; I'm sure that there are many acceptable alternatives:

    (DO-ALL-CHARACTERS (char registry)                      [Macro]
    	body)

In particular, I would point out that requiring the available
characters to be documented is sufficient only for some users of
commercial implementations.  Students, users of non-commercial
implementations, and an unfortunate number of business users have to
get by with little or no access to printed documentation.

Specific comments:

Page 8: paragraph 2 <The proposed ISO...>

Is this meant to be a proposal from X3J13 to the not-yet-existent ISO
working group?  X3J13 certainly can't make a pronouncement about the
contents of a unwritten ISO Character Registry Standard.

Page 8: paragraph 3

In other words, implementations can subset character registries but
not expand them?

Straw Ballot:

	Issue: CHAR-FONT-UNUSED-CHAR-BITS-NONPORTABLE
	Problem: CHAR-FONT isn't used, CHAR-BITS isn't portable.
	Proposal:
		  Eliminate of font and bit attributes.
		  Add rules for an implementation supporting attributes.

    The only reference I can find to implementation defined attributes is
    footnote 3 at the bottom of page 6.  Either the "rules" mentioned
    above should be added to the proposal or this part of the issue should
    be dropped.
		  Redefine STRING-CHAR as implementation defined.
		  Remove CHAR-FONT-LIMIT
		  Remove CHAR-BITS-LIMIT
		  Remove INT-CHAR
		  Remove CHAR-BITS
		  Remove CHAR-FONT
		  Remove MAKE-CHAR
		  Remove CHAR-CONTROL-BIT
		  Remove CHAR-META-BIT
		  Remove CHAR-SUPER-BIT
		  Remove CHAR-HYPER-BIT
		  Remove CHAR-BIT
		  Remove SET-CHAR-BIT
IF: see above

	Issue: CHAR-INT-ONLY-USEFUL-WHEN-ATTRIBUTES-SUPPORTED
	Problem: CHAR-INT behavior is CHAR-CODE unless implementation
	  defined attributes are supported.
	Proposal:
		  Remove CHAR-INT
IF: Moon agrees that this is sufficient for hashing (or I'm convinced that
he's wrong :-)).


	Issue: CHARACTER-TYPE-RESTRICTIVEC
	Problem: CHARACTER type doesn't allow thin & fat characters.
	Proposal:
		  Define BASE-CHARACTER as a subtype of STRING.
		  Standard characters are a subset of the base
		     characters.
		  STANDARD-CHAR type is replaced by (CHARACTER :STANDARD)
		  Remove the semi-standard characters.
YES


	Issue: STRING-TYPE-RESTRICTIVE
	Problem: STRING type doesn't allow thin & fat strings.
	Proposal:
		  Define STRING as a union type
		  STRING used as a type specifier for object creation
		     means (VECTOR CHARACTER)
		  All string functions operate as specified on any
		     string object except it is an error to insert
		     an extended character into a base string.

    What do STRING-LESSP, etc. mean for non-standard-character strings?

		  Extend the COERCE function to allow coercion from
		    base string to extended string.

IF: the above is resolved, possibly by explictly saying it's undefined.

	Issue: STRING-TYPE-ABBREVIATIONS
	Problem: new types are awkward to name, want abbreviations.
	Proposal:
		  Add BASE-STRING
		  Add GENERAL-STRING
YES

	Issue: SIMPLE-STRING-TYPE-RESTRICTIVE
	Problem: SIMPLE STRING type doesn't allow thin & fat strings.
	Proposal:
		  Define SIMPLE-STRING as a union type
		  Define SIMPLE-STRING as a type specifier for object
		     creation means (SIMPLE-ARRAY CHARACTER (size))
YES


	Issue: SIMPLE-STRING-TYPE-ABBREVIATIONS
	Problem: new types are awkward to name, want abbreviations.
	Proposal:
		  Add SIMPLE-BASE-STRING
		  Add SIMPLE-GENERAL-STRING
YES


	Issue: FILE-EXTERNAL-REPRESENTATION
	Problem: can't specify external encoding even when there are lots
	Proposal:
		  Add :EXTERNAL-CODED-CHARACTER-FORMAT keyword to OPEN
YES


	Issue: STRING-BINARY-WIDTH
	Problem: Can't find out how many bytes a string will take when
	written as text
	Proposal:
		  Add :EXTERNAL-CODED-STRING-LENGTH function
YES
I think that reference to "terminal screen templates" has confused
some people without adding to the content.


	Issue: CHAR-CODE-NON-PORTABLE
	Problem: no way to talk about well-known external coding methods, only
	internal codes
	Proposal:
		  Add CHAR-CCS-VALUE function
YES


	Issue: CHARACTER-IDENTIFICATION-NONPORTABLE
	Problem: Can't portably talk about non-standard characters
	Proposal:
		   Introduce the concept of Registries
		   Standardize on #\registry:id, add all-implemented-registries
		   Add *ALL-CHARACTER-REGISTRY-NAMES* variable
		   Add FIND-CHAR function
		   Add CHAR-LABEL function
		   Add CHAR-REGISTRY-NAME function
		   New syntax for CHARACTER type specifier
		   New #\label:registry character name syntax
		   New argument to CHARACTERP
NO: Unless the issues raised in the first part of this message are resolved.

∂01-Mar-89  1335	X3J13-mailer 	Re: Section 1.7 
Received: from multimax.encore.com by SAIL.Stanford.EDU with TCP; 1 Mar 89  13:35:17 PST
Received: from mist.encore.COM by multimax.encore.com with SMTP (5.61/25-eef)
	id AA20628; Wed, 1 Mar 89 16:31:49 -0500
Received: from localhost by mist. (4.0/SMI-4.0)
	id AA11532; Wed, 1 Mar 89 16:29:55 EST
Message-Id: <8903012129.AA11532@mist.>
To: Barry Margolin <barmar@Think.COM>
Cc: "chapman%aitg.DEC@decwrl.dec.com"@Multimax.encore.com,
        x3j13@sail.stanford.edu,
        "skona%csilvax@hub.ucsb.edu"@multimax.encore.com
Subject: Re: Section 1.7 
In-Reply-To: Your message of Wed, 01 Mar 89 16:01:00 -0500.
             <19890301210123.2.BARMAR@OCCAM.THINK.COM> 
Date: Wed, 01 Mar 89 16:29:54 EST
From: Dan L. Pierson <pierson@mist.encore.com>

    - It restricts the definition to tools described in the standard.
    Implementations are expected to provide their own tools in their own
    packages, and I don't think these are considered extensions (this would
    require an implementation to litter its documentation with "this is an
    extension to Common Lisp" on nearly every page).
    
I'm not sure I agree with you here.  Lucid certainly documents every
new "tool" as "a Lucid extension to Common Lisp" and this doesn't seem
to unduely clutter their documentation.

∂01-Mar-89  1526	X3J13-mailer 	minor comments on letter ballot material 
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 1 Mar 89  15:26:35 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 548782; Wed 1-Mar-89 18:22:47 EST
Date: Wed, 1 Mar 89 18:22 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: minor comments on letter ballot material
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@SAIL.STANFORD.EDU, skona%csilvax@hub.ucsb.edu
Message-ID: <19890301232245.6.MOON@EUPHRATES.SCRC.Symbolics.COM>

Here are some minor comments about the material that you mailed out
with your letter ballot.  This is not an official response to the
letter ballot.

I like the terms in the error-terminology proposal, however the
meanings of the terms are rather sloppily written.  To take one
example, for "the consequences are unspecified", it says that
implementations are permitted to specify the consequences.  However,
for "the consequences are undefined", it neither says that
implementations are permitted to specify the consequences, nor
that they are not.  I noticed a few other things that might be
inconsistencies or ambiguities in these descriptions.  I also
noticed that the reference sections in the letter ballot do not
actually use this error terminology, for the most part.  I assume
these deficiencies are just due to the schedule, and will be
corrected before the final draft.  I would certainly recommend
putting a lot of time into the exact wording of the definitions
of the error terminology, since that will have high leverage for
the understanding of the rest of the specification.  CLtL suffered
greatly because we did not do this.  I don't think it's effective
for the committee of the whole to argue over that exact wording,
I think it would be more appropriate for 2 or 3 people on the
editorial committee to write the whole set of descriptions at
one time in a consistent and unambiguous style.  (On the subject
of implementations specifying the consequences, I see no advantage
to the standard forbidding implementations to say anything about
what the particular implementation will do in situations that
conforming programs are forbidden to depend upon.)

On page 2-12 of section 2.3, the second to last paragraph came from
something in 88-002R that said that CLtL doesn't specify some class
orderings but CLOS does.  Now that CLtL and CLOS are not two separate
standards, this no longer makes sense.  You don't need to talk about
classes being layered on top of a preexisting type system defined by
somebody else.  Possibly you should delete all but the first sentence of
this paragraph.

The table of built-in classes on page 2-13 is missing a great many
entries.  Now that cleanup issue DATA-TYPES-HIERARCHY-UNDERSPECIFIED has
passed, the types HASH-TABLE, READTABLE, PACKAGE, PATHNAME, STREAM, and
RANDOM-STATE should be added to this table.  I also believe that the
passage of FUNCTION-TYPE means that FUNCTION should be added to this
table, although I'm less confident there.  Each one of these classes
has a CPL consisting of just itself and T.  Do you need a separate
cleanup issue to be passed to do this?

Page 2-24 says implementations are permitted to make certain
optimizations, but does not say what they are.  This paragraph
came from page 1-42 of 88-002R, which did say (or pointed to
where it is said.)  Note: I have not done a line by line
comparison of this document with 88-002R and I have no intention
of doing so.  This is just a discrepancy that jumped out at me.

Page 2-9 says "Updating an instance does not change its identity as
defined by the EQ function".  Page 2-24 does not say "Changing the class
of an instance does not change its identity as defined by the EQ
function".  My belief is that it was the intent of the CLOS committee to
say that, although 88-002R fails to say it.  Do you need a separate
cleanup issue to be passed to fix this?

Here's a suggestion from one of our CLOS implementors.  Would this
change (adding the word "affected") require a vote?

Page 2-9 Redefining Classes

   Updating such an instance occurs at an implementation-dependent time,
   but no later than the next time a slot of that instance is read or written.

I think I'd prefer if this said:

   Updating such an instance occurs at an implementation-dependent time,
   but no later than the next time an affected slot of that instance is
   read or written.

I (Moon again) think this is a good idea.

∂01-Mar-89  1853	X3J13-mailer 	Re: minor comments on letter ballot material  
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 1 Mar 89  18:53:24 PST
Received: from Semillon.ms by ArpaGateway.ms ; 01 MAR 89 18:46:12 PST
Date: Wed, 1 Mar 89 18:45 PST
From: Gregor.pa@Xerox.COM
Subject: Re: minor comments on letter ballot material
To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
cc: chapman%aitg.DEC@decwrl.dec.com, x3j13@SAIL.STANFORD.EDU,
 skona%csilvax@hub.ucsb.edu
Fcc: BD:>Gregor>mail>outgoing-mail-5.text.newest
In-Reply-To: <19890301232245.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890302024559.5.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no

    Date: Wed, 1 Mar 89 18:22 EST
    From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>

    Here's a suggestion from one of our CLOS implementors.  Would this
    change (adding the word "affected") require a vote?

    Page 2-9 Redefining Classes

       Updating such an instance occurs at an implementation-dependent time,
       but no later than the next time a slot of that instance is read or written.

    I think I'd prefer if this said:

       Updating such an instance occurs at an implementation-dependent time,
       but no later than the next time an affected slot of that instance is
       read or written.

    I (Moon again) think this is a good idea.

This change makes is impossible for people to use MAKE-INSTANCES-OBSOLETE
to arrange for any future access to the slots of an instance to trap.
One of the reasons we gave for not adding an instance enumeration
mechanism was the availability of this functionality.  So, I don't think
we should make this change.

I agree that the other change you suggested (change-class vs. eq) is in
line with our original intent and we should go ahead and make it.  I
hope it doesn't require a vote.

    Page 2-9 says "Updating an instance does not change its identity as
    defined by the EQ function".  Page 2-24 does not say "Changing the class
    of an instance does not change its identity as defined by the EQ
    function".  My belief is that it was the intent of the CLOS committee to
    say that, although 88-002R fails to say it.  Do you need a separate
    cleanup issue to be passed to fix this?


-------

∂01-Mar-89  2340	X3J13-mailer 	Section 2.2, part 1  
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 1 Mar 89  23:38:50 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA07792; Wed, 1 Mar 89 23:36:51 PST
Message-Id: <8903020736.AA07792@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
	for x3j13@sail.stanford.edu; id AA07792; Wed, 1 Mar 89 23:36:51 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 2 Mar 89 02:32
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: Section 2.2, part 1

%% Types - part 1
%% Type Hierarchy and Relationships
\beginsubSection{Type Hierarchy and Relationships}
Figure {\chapno--\the\capno}
depicts the @clisp\ type hierarchy and relationships.
An explanation of the 
relationships of data types to each other follows.
 
\beginlist
%% 2.15.0 4
\itemitem{\bull} {\datatype t} is a {\word supertype} of every type whatsoever.
Every {\word object} is of type {\datatype t}.
 
%% 2.15.0 5
\itemitem{\bull} {\datatype Nil} is a {\word subtype} of every type whatsoever.
No {\word object} is of type {\datatype nil}.
 
\issue{DATA-TYPES-HIERARCHY-UNDERSPECIFIED}
The following will be left out of the standard.
%% 2.15.0 6
\itemitem{\bull} {\datatype Cons}, {\datatype symbol},         
{\datatype array}, {\datatype number}, and {\datatype character}
are pairwise {\word disjoint}.
\endissue{DATA-TYPES-HIERARCHY-UNDERSPECIFIED}
 
%% 2.15.0 7            
\itemitem{\bull} {\datatype Rational}, {\datatype float}, and {\datatype complex} 
are pairwise {\word disjoint}
{\word subtypes} of {\datatype number}.
 
%% 2.15.0 8            
\itemitem{\bull} {\datatype Integer} 
and {\datatype ratio} are {\word disjoint subtypes }
of {\datatype rational}.
 
%% 2.15.0 10                                
\itemitem{\bull} 
{\datatype Fixnum} and {\datatype bignum} 
are {\word disjoint} {\word subtypes} of {\datatype integer}.
 
%% 2.15.0 12
\itemitem{\bull}             
{\datatype Short-float}, {\datatype single-float}, {\datatype double-float}, and
{\datatype long-float} are {\word subtypes} of {\datatype float}.  
Any two of them must be
either {\word disjoint} or identical; 
if identical, then any other types between
them in the above ordering must also be identical to them
(for example, if {\datatype single-float} and {\datatype long-float} 
are identical, 
then {\datatype double-float} must be identical to them also).
 
 
 
%% 2.15.0 13
\itemitem{\bull} {\datatype Null} is a 
{\word subtype} of {\datatype symbol}; the only {\word object} of 
type
{\datatype null} is @nil\rm.
 
%% 2.15.0 14
\itemitem{\bull} {\datatype Cons} and {\datatype null} 
form an {\word exhaustive partition} of 
{\datatype list}.
 
 
%% 2.15.0 15              
\itemitem{\bull} {\datatype Standard-char} is a {\word subtype} 
of {\datatype string-char};
{\datatype string-char} is a {\word subtype} of {\datatype character}.
 
%% 2.15.0 16                          
\itemitem{\bull} {\datatype String} is a 
{\word subtype} of {\datatype vector}.
{\datatype String}                
is identical to {\tt (vector string-char)}, which in turn
is the same as {\tt (array string-char (*))}.
 
%% 2.15.0 17                  
\itemitem{\bull} {\datatype Bit-vector} 
is a {\word subtype} of {\datatype vector}, for {\datatype bit-vector}
means {\tt (vector bit)}.
 
%% 2.15.0 18
\itemitem{\bull} {\tt (vector t)} and 
{\datatype string}, and {\datatype bit-vector} are {\word disjoint}.
 
%% 2.15.0 19
\itemitem{\bull} {\datatype Vector} is a 
{\word subtype} of {\datatype array}; 
for all types @f[x]\rm,
{\tt (vector x)} is the same as 
{\tt (array x (*)).}
  
%% 2.15.0 20        
\itemitem{\bull} {\datatype Simple-array} is a {\word subtype} 
of {\datatype array}.
 
%% 2.15.0 21
\itemitem{\bull} {\datatype Simple-vector}, {\datatype simple-string}, and
{\datatype simple-bit-vector} are 
{\word disjoint subtypes} of {\datatype simple-array}, for they
respectively mean 
{\tt (simple-array t (*))}, {\tt (simple-array string-char (*))},
and {\tt (simple-array bit (*))}.
 
%% 2.15.0 22                       
\itemitem{\bull} {\datatype Simple-vector} is a {\word subtype} 
of {\datatype vector}, 
and is
a {\word subtype} of {\tt (vector t)}.
 
%% 2.15.0 23                                                           
\itemitem{\bull} {\datatype Simple-string} is a 
{\word subtype} of {\datatype string}.
 
%% 2.15.0 25
\itemitem{\bull} {\datatype Simple-bit-vector} 
is a {\word subtype} of {\datatype bit-vector}.
 
%% 2.15.0 26                                                 
\itemitem{\bull} {\datatype Vector} and {\datatype list} 
are {\word disjoint subtypes} of {\datatype sequence}.
 
\issue{DATA-TYPES-HIERARCHY-UNDERSPECIFIED}
The following will be left out of the standard.
%% 2.15.0 27
\itemitem{\bull} {\datatype Hash-table}, {\datatype readtable}, 
{\datatype package}, {\datatype pathname},
{\datatype stream}, and {\datatype random-state} are {\word pairwise disjoint}.
\endissue{DATA-TYPES-HIERARCHY-UNDERSPECIFIED}
 
\issue{DATA-TYPES-HIERARCHY-UNDERSPECIFIED}
\itemitem{\bull} The types {\datatype cons}, 
{\datatype symbol}, {\datatype array}, 
{\datatype number}, {\datatype character}, {\datatype hash-table}, 
\issue{FUNCTION-TYPE:X3J13-MARCH-88}
{\datatype function},
\endissue{FUNCTION-TYPE:X3J13-MARCH-88}
{\datatype readtable},
  {\datatype package}, {\datatype pathname}, {\datatype stream}, 
{\datatype random-state}, and any single other type created
  by {\function defstruct} or {\function defclass} are pairwise disjoint.
\endissue{DATA-TYPES-HIERARCHY-UNDERSPECIFIED}
 
 
%% 2.15.0 28
\itemitem{\bull} Any two types created by @Macref[defstruct] are {\word disjoint} unless
one is a {\word supertype} of the other by virtue of
the {\function defstruct} {\keyword :include} option.
 
\itemitem{\bull} Any two classes created by {\function defclass} are disjiont
unless one is a superclass of the other.
 
%% 2.15.0 29
\itemitem{\bull} An {\word exhaustive union} for {\datatype common} is formed by 
{\datatype cons}, {\datatype symbol}, {\tt (array x)} where @f[x] 
is either {\datatype t} or 
a {\word subtype}
of {\datatype common}, {\datatype string}, {\datatype fixnum}, {\datatype
bignum}, {\datatype ratio},
{\datatype short-float}, {\datatype single-float}, {\datatype double-float}, 
{\datatype long-float},
{\tt (complex x)} where @f[x] is a
{\word subtype} of {\datatype common},
{\datatype standard-char}, {\datatype hash-table}, {\datatype readtable}, 
{\datatype package}, {\datatype pathname},
{\datatype stream}, {\datatype random-state}, and all types 
created by the user
via @Macref[defstruct]\rm.
An implementation may not add {\word subtypes} to
{\datatype common}.
 
\endlist                                     
%%kc2
  
\eject
\fig{
\def\IgnoreLineBreaks{\catcode'15=9     \catcode'12=9}
\def\IgnoreWhiteSpace{\catcode'11=9 \catcode'40=9 \IgnoreLineBreaks}
\def\DontIgnoreWhiteSpace{\catcode'12=\active\catcode'15=5\catcode'11=10\catcode'40=10}
 
\font \pipefont= circle10
 
\font \foofont = amr10 at 1sp
 
\IgnoreWhiteSpace
 
\let \adv=\advance
\def\he{height}
\def\wi{width}
\def\de{depth}
 
\newdimen \stroke       
\stroke= \fontdimen8\pipefont   % thickness of line in circles
\newdimen \radius       \radius=6pt     % radius of circles
 
\newdimen\irad \irad=\radius\advance\irad by -.5\stroke
\newdimen\orad \orad=\radius\advance\irad by  .5\stroke
 
\newbox\BStrutbox
 
\setbox\BStrutbox\hbox{\vrule\wi0pt\he10pt\de10pt}
\def\BoxStrut{\unhcopy\BStrutbox}
 
!% Arrows
 
\newdimen\ArrowShift
\ArrowShift=\fontdimen22\tensy
\advance\ArrowShift by -0.5\stroke
 
\def\StrikeOut #1
{       \setbox0\hbox{#1}
        \hbox to 1\wd0
        {       \vrule \he\stroke\de0pt\wi\wd0
                \hskip-\wd0
                \unhbox0
        }
}
 
\def\LeftArrow
{       \hskip 0.5\stroke
        \StrikeOut{\lower\ArrowShift\hbox to 10pt{\tensy\char'40\hss}}
}
 
\def\RightArrow
{       \StrikeOut{\lower\ArrowShift\hbox to 10pt{\hss\tensy\char'41}}
        \hskip 0.5\stroke
}
 
\def\ArrowLine
{       \StrikeOut{\hskip 10pt\hskip 0.5\stroke}
}
 
\def\LeftToRight
{       \let\RightSideArrow=\ArrowLine
        \let\LeftSideArrow=\RightArrow
}
 
\def\RightToLeft
{       \let\LeftSideArrow=\ArrowLine
        \let\RightSideArrow=\LeftArrow
}
 
\def\NoArrows
{       \let\LeftSideArrow=\ArrowLine
        \let\RightSideArrow=\ArrowLine
}
!% boxes around tokens
 
\let\NonterminalFont=\tenrm
 
\newbox\TStrutbox
\setbox0\hbox{\NonterminalFont{Bg}}
\setbox\TStrutbox\hbox{\vrule\wi0pt\he\ht0\de\dp0}
\def\TextStrut{\unhcopy\TStrutbox}
 
\def\HorzLine{\hrule \he \stroke \de 0pt}
\def\HFil{\leaders\HorzLine\hfil}
\def\HFill{\leaders\HorzLine\hfill}
 
\def\Nonterminal#1
{\setbox1\vbox to 0pt{
        \vss
        \hbox{\TextStrut\NonterminalFont\space#1\space\hskip-\stroke}
        \vss}
        \hbox{
        \BoxStrut
        \LeftSideArrow
        \lower\irad\vbox{
                \TopSquare
                \copy1
                \BotSquare}
        \RightSideArrow}
}
 
\def\TopSquare
{       \hbox{
        \vrule\he\stroke\de\irad\wi\stroke
        \vrule\he\stroke\de0pt\wi\wd1
        \vrule\he\stroke\de\irad\wi\stroke}
}
 
\def\BotSquare
{       \hbox{
        \vrule\he\orad\de0pt\wi\stroke
        \vrule\he\stroke\de0pt\wi\wd1
        \vrule\he\orad\de0pt\wi\stroke}
}
 
\def\\#1{\Nonterminal{#1}\HFil}
\def\last#1{{\def\RightSideArrow{}\Nonterminal{#1}}}
 
!% piping
 
\def\foo{\rlap{\foofont\char'40}}
 
\def\FulVert{\vrule             \wi\stroke\foo\hskip-\stroke}
\def\TopVert{\vrule\de-\irad    \wi\stroke\foo\hskip-\stroke}
\def\BotVert{\vrule\he-\orad    \wi\stroke\foo\hskip-\stroke}
 
\def\Center#1,#2.
{\hskip\radius\foo#1\lower.5\stroke\hbox{\pipefont#2}\hskip\radius}
 
\def\ru{\char'10\hskip -2\radius}
\def\rd{\char'11\hskip -2\radius}
\def\ld{\char'12\hskip -2\radius}
\def\lu{\char'13\hskip -2\radius}
\def\thru{\hskip-\radius\vrule\he\stroke\de0pt\wi2\radius\hskip\radius\hskip-2\radius}
 
\def\Center#1,#2.
{\foo\hskip\radius#1{\pipefont#2\unskip}\hskip-\radius}
 
\def\LT{\Center\BotVert,\lu.}
\def\LU{\Center\FulVert,\lu.}
\def\LL{\Center\FulVert,\ld.}
\def\LB{\Center\TopVert,\ld.}
\def\LMid{\Center\TopVert\BotVert,\rd\ru\thru.}
\def\LMU{\Center\TopVert,\rd\thru.}
\def\LML{\Center\BotVert,\ru\thru.}
\def\LFD{\Center\FulVert,\ru\thru.}
\def\LS{\Center\TopVert\BotVert,\rd\ru.}
 
\def\RT{\Center\BotVert,\ru.}
\def\RU{\Center\FulVert,\ru.}
\def\RL{\Center\FulVert,\rd.}
\def\RB{\Center\TopVert,\rd.}
\def\RMid{\Center\TopVert\BotVert,\ld\lu\thru.}
\def\RMU{\Center\TopVert,\ld\thru.}
\def\RML{\Center\BotVert,\lu\thru.}
 
\def\Cross{\Center\FulVert,\thru.}
\def\LR{\Center,\thru.}
\def\TB{\Center\FulVert,.}
!%  ShiftBox
 
\newbox\x
\newbox\y
\newbox\tempy
\newbox\z
\newbox\tempz
 
\def\ShiftBox#1{
\savemod
\saverulebox
\setbox\x
\vbox{  \everycr{\noalign{{\modifyrulebox\global\setbox\z\hbox{}}}}
        \halign{&\setbox\x\hbox{##}
        \global \setbox\z\hbox{\unhbox\z\vrule\he\ht\x\de\dp\x\wi0pt}
                \unhbox\x
                \cr
                #1}}%
\lower\ht\y\box\x\HFil
\restoremod
\restorerulebox
}
 
\def\saverulebox{
        \setbox\tempy\box\y
\global \setbox\y\vbox{}
        \setbox\tempz\box\z
\global \setbox\z\hbox{}
}
 
\def\restorerulebox{
\global \setbox\y\box\tempy
\global \setbox\z\box\tempz
}
 
\def\topmod{}
 
\def\thisrow{\global\let\modifyrulebox\firstmod}
 
\def\firstmod{
        \global\setbox\y\vbox{\hrule\he0pt\wi0pt\de\dp\z}
        \global\let\modifyrulebox\latermod
}
\def\latermod{
        \global\setbox\y\vbox{\unvbox\y\hrule\he\ht\z\de\dp\z\wi0pt}
}
\def\savemod{
        \let\tempmod\modifyrulebox
\global \let\modifyrulebox\topmod
}
\def\restoremod{
\global\let\modifyrulebox\tempmod
}
 
\DontIgnoreWhiteSpace
!{\baselineskip0pt
\lineskip0pt
\LeftToRight
\IgnoreWhiteSpace
 
\def\ms{\os     
\os\os\os}
\def\os{\omit\span}
\hbox{
\\{nil}
\ShiftBox{
    \ms\ShiftBox{
        \ShiftBox{
            \ShiftBox{
                \LT\\{fixnum}&\RT\cr
                \LU\\{bignum}&\RMU\thisrow\cr
                }\\{integer}&\RML\thisrow\cr
            \LU\\{ratio}&\RB\cr
            }\\{rational}&\RT\cr
        \ShiftBox{
            \LU\\{short-float}&\RT\cr
            \LU\\{single-float}&\RMid\thisrow\cr
            \LU\\{double-float}&\RL\cr
            \LU\\{long-float}&\RB\cr
            }\\{float}&\RMid\thisrow\cr
        \LU\\{complex}&\RB\cr
        }\\{number}&\RT\cr
    \ms\LU\\{standard-char}\\{string-char}\\{character}&\RU\cr
    \LU\\{null}&\os\os\os\LML\\{symbol}&\RU\cr
    \LMid\\{cons}&\os\os\RMU\\{list}&\RML\\{sequence}&\RMid\thisrow\cr
    \os\LL\\{simple-vector}&\LML\HFil&\RML\\{vector}&\LS&\TB\cr
    \os\LL\\{simple-bit-vector}&\LFD\\{bit-vector}&\RL&\TB&\TB\cr
    \os\LL\\{simple-string}&\LFD\\{string}&\RB&\TB&\TB\cr
    \os\TB&\os\LB\HFil\\{simple-array}&\RMU\\{array}&\RL\cr
    \ms\LL\\{function}\\{compiled-function}&\RL\cr
    \ms\LL\\{stream}&\RL\cr
    \ms\LL\\{hash-table}&\RL\cr
    \ms\LL\\{readtable}&\RL\cr
    \ms\LL\\{package}&\RL\cr
    \ms\LL\\{pathname}&\RL\cr
    \ms\LL\\{random-state}&\RL\cr
    \ms\LB\\{structures}&\RB\cr
}
\last{t}}}
}\caption{Relationships among the Common Lisp data types}
\endfig              
\eject
%%kc1
\endsubSection%{Type Hierarchy and Relationships}
                   
\beginsubSection{Data Type Definition}
Following is a description of each @clisp\ {\word type}.
 
 
%% 2.0.0 6
\beginsubsubsection{\datatype t}
 
The set of all {\word objects} is specified
by @true\rm.  
 
\beginsubsubsection{\datatype Number} 
 
The type {\datatype number\/} is composed of the pairwise {\word disjoint}
{\datatype rational}, {\datatype float}, and {\datatype complex\/} subtypes\/. 
An {\word object} of type {\datatype number\/} is called a {\datatype
number\/}.
%% 12.0.0 4
Two {\datatype numbers\/} that are {\function eql} or 
{\function =} are not necessarily {\function eq}.
 
The contagion rules for implicit coercions of arguments in 
{\word operations} follow:
\beginlist
\itemitem{\bull}
When a {\word shorter}
{\datatype floating-point} number is combined with a longer one in an 
operation,
the result will be of the {\word type} of the longer 
of the two {\datatype floating-point} numbers.
\issue{CONTAGION-ON-NUMERICAL-COMPARISONS:TRANSITIVE)}
\itemitem{\bull}
For {\word functions} that combine arguments of different {\word types},
when one argument is a {\datatype rational} and the other is 
a {\datatype floating-point} number,
the {\datatype rational} is first 
converted to a {\datatype floating-point} number of
the same format.  
For {\word functions} that compare arguments of different {\word types},
when one argument is a {\datatype rational} and the other is 
a {\datatype floating-point} number, the function
{\function rational} is effectively
called to convert the {\datatype floating-point} 
number to a {\datatype rational} and then an exact
comparison is performed. In the case of {\datatype complex\/} 
numbers, the real and 
imaginary parts are handled individually.
\endissue{CONTAGION-ON-NUMERICAL-COMPARISONS:TRANSITIVE)}
\itemitem{\bull}
When a non-{\datatype complex\/} 
number meets a {\datatype complex\/} number, the non-{\datatype complex\/}
number is in effect first converted to a 
{\datatype complex\/} number by providing an
imaginary part of {\tt $0$}.
\endlist
 
%% 12.5.3 1
Many of the irrational and transcendental functions are multiply defined
in the complex domain; for example, there are in general an infinite
number of complex values for the logarithm function.  In each such
case, a principal value must be chosen for the function to return.
In general, such values cannot be chosen so as to make the range
continuous; lines in the domain
called branch cuts must be defined, which in turn
define the discontinuities in the range.
%% 12.5.3 2
@clisp\ defines the branch cuts, principal values, and boundary
conditions for the complex functions following
@apl\rm.
 
%% 12.7.0 1
%% 12.7.0 2
Logical operations require {\datatype integers}
as arguments; an error of type {\datatype type-error}
is signalled if a non-{\datatype integer} is supplied
as an argument.
{\datatype Integer} arguments to logical operations are treated as if
they were represented in two's-complement notation.
Internally an implementation 
may or may not use a two's-complement representation.
 
%% 12.8.0 2
The byte-manipulation {\word forms} 
use {\word objects} called byte specifiers to
designate a specific byte position within an {\datatype integer}.
The representation of a byte specifier is implementation-dependent ---
it may or may not be a {\datatype number}.
The function {\function byte} will construct a byte specifier,
and the byte-manipulation {\word forms} will accept it.
 
The following figures contain lists of {\word tools} applicable to 
{\datatype numbers}.
 
Figure {\chapno--\the\capno} lists the number predicate and comparison
{\word tools}.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt zerop }&{\tt  plusp }&{\tt  minusp }\cr
{\tt oddp }&{\tt  evenp } &{\tt  = }\cr
{\tt /= }&{\tt  < } &{\tt  > }\cr
{\tt <= }&{\tt  >= } &{\tt  max }\cr
{\tt min} & & \cr
\noalign{\vskip -9pt}
}}
\caption{Number tools - 1}
\endfig
 
 
 
Figure {\chapno--\the\capno} lists the {\word tools} for arithmetic operations.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt + }&{\tt  - } &{\tt  * }\cr
{\tt / }&{\tt  1+ } &{\tt  1-  }\cr
{\tt incf }&{\tt  decf } &{\tt  conjugate }\cr
{\tt gcd }&{\tt  lcm } & \cr
\noalign{\vskip -9pt}
}}
\caption{Number tools - 2}
\endfig
 
 
 
Figure {\chapno--\the\capno} lists the {\word tools} 
for exponential, logarithmic, and trigonometric operations.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt exp }&{\tt  expt } &{\tt  log }\cr
{\tt sqrt }&{\tt  isqrt } &{\tt  abs }\cr
{\tt phase }&{\tt  signum } &{\tt  sin }\cr
{\tt cos }&{\tt  tan } &{\tt  cis }\cr
{\tt asin }&{\tt  acos } &{\tt  atan }\cr
{\tt pi }&{\tt  sinh } &{\tt  cosh }\cr
{\tt tanh }&{\tt  asinh } &{\tt  acosh }\cr
{\tt atanh }& &\cr
\noalign{\vskip -9pt}
}}
\caption{Number tools - 3}
\endfig
 
 
Figure {\chapno--\the\capno} lists the {\word tools} 
for type conversion and component extraction operations.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt float }&{\tt  rational} &{\tt rationalize } \cr
{\tt  numerator} & {\tt denominator }& {\tt floor} \cr
{\tt ceiling} & {\tt truncate} & {\tt round} \cr
{\tt mod} & {\tt rem} & {\tt ffloor}\cr
{\tt fceiling} & {\tt ftruncate} & {\tt fround}\cr
{\tt decode-float} & {\tt scale-float} & {\tt float-radix}\cr 
{\tt float-sign} & {\tt float-digits} & {\tt  float-precision}\cr
{\tt integer-decode-float} & {\tt complex} & {\tt realpart}\cr
{\tt imagpart} & & \cr
\noalign{\vskip -9pt}
}}
\caption{Number tools - 4}
\endfig
 
 
 
 
Figure {\chapno--\the\capno} lists the logical operation {\word tools}.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt logior} & {\tt logxor} & {\tt logand} \cr
{\tt logeqv} & {\tt lognand} & {\tt lognor} \cr
{\tt logandc1} & {\tt logandc2 }&{\tt  logorc1 } \cr
{\tt logorc2 } & {\tt boole }&{\tt  boole-clr }\cr
{\tt boole-set } & {\tt boole-1 }&{\tt  boole-2 }\cr
{\tt boole-c1 } & {\tt boole-c2 }&{\tt  boole-and }\cr
{\tt boole-ior } & {\tt boole-xor }&{\tt  boole-eqv }\cr
{\tt boole-nand } & {\tt boole-nor }&{\tt  boole-andc1 }\cr
{\tt boole-andc2 } & {\tt boole-orc1 }&{\tt  boole-orc2 }\cr
{\tt lognot } & {\tt logtest }&{\tt  logbitp }\cr
{\tt ash } & {\tt logcount} & {\tt integer-length }\cr
\noalign{\vskip -9pt}
}}
\caption{Number tools - 5}
\endfig
 
 
Figure {\chapno--\the\capno} lists the byte manipulation {\word tools}.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt byte} &{\tt byte-size} & {\tt byte-position}\cr 
{\tt ldb} & {\tt ldb-test} & {\tt mask-field} \cr
{\tt dpb} & {\tt deposit-field} & \cr
\noalign{\vskip -9pt}
}}
\caption{Number tools - 6}
\endfig
 
 
 
Figure {\chapno--\the\capno} lists the implementation-dependent parameters.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt most-positive-fixnum }& {\tt most-negative-fixnum }\cr
{\tt most-positive-short-float } &{\tt least-positive-short-float} \cr
{\tt least-negative-short-float} & {\tt most-negative-short-float} \cr 
{\tt most-positive-single-float } & {\tt least-positive-single-float} \cr
{\tt least-negative-single-float} & {\tt most-negative-single-float} \cr
{\tt most-positive-double-float} & {\tt least-positive-double-float} \cr
{\tt least-negative-double-float} & {\tt most-negative-double-float} \cr
{\tt most-positive-long-float} &{\tt least-positive-long-float} \cr
{\tt least-negative-long-float} & {\tt most-negative-long-float} \cr
{\tt short-float-epsilon} & {\tt single-float-epsilon} \cr
{\tt double-float-epsilon} & {\tt long-float-epsilon} \cr
{\tt short-float-negative-epsilon} & {\tt single-float-negative-epsilon}\cr
{\tt double-float-negative-epsilon}& {\tt long-float-negative-epsilon}  \cr
\noalign{\vskip -9pt}                                       
}}
\caption{Number tools - 7}
\endfig
 
\beginsubsubsection{\datatype Rational} 
 
The type {\datatype
rational} is composed of the {\word disjoint}
{\datatype integer} and {\datatype                         
ratio} subtypes. 
An {\word object} of type {\datatype rational\/} is called a {\datatype
rational}.
 
%% 12.1.0 2
The following rules apply to {\datatype rational} computations.
\beginlist
\itemitem {--} Rational computations cannot overflow in the usual sense
(though there may not be enough storage
to represent one), since 
{\datatype integers} and {\datatype ratios} 
may in principle be of any magnitude.
            
%% 2.1.2 1         
 
\itemitem {--} The representation of a 
{\datatype rational} number is as the ratio of two
integers, the numerator and denominator, where the greatest common divisor of
the numerator and denominator is one, and where the denominator is positive
and greater than one. If the value of a {\datatype rational} is 
an {\datatype integer}, it is
represented as an integer.
 
%% 2.1.2 2
%% 12.1.0 5
\itemitem{--} If any computation produces 
a result that is a {\datatype ratio} of
two {\datatype integers} such that the denominator evenly divides the
numerator, then the result is converted to the equivalent
{\datatype integer}.  
 
%% 12.1.0 3
\itemitem{--} When 
{\datatype rational} and {\datatype floating-point} numbers 
are compared or combined by
a numerical {\word function}, 
the {\datatype rational} 
is first converted to a {\datatype floating-point} number of
the same format.  For {\word forms} such as {\function +}
that take more than two arguments,
it is permitted that part of the operation be carried out exactly using
{\datatype rationals} 
and the rest be done using floating-point arithmetic.
 
 
%% 12.5.0 4
\itemitem{--} 
When the arguments to
a mathematical 
{\word function} are all {\datatype rational} and the true mathematical result
is also (mathematically) rational, then unless otherwise noted
an implementation is free to return either an accurate
{\datatype rational} result
or a {\datatype single-float} approximation.
If the arguments are all {\datatype rational} 
but the result cannot be expressed
as a {\datatype rational} number, then a {\datatype single-float} 
approximation is always returned.
 
\endlist
 
 

∂02-Mar-89  0008	X3J13-mailer 	Section 2.2 - part 3 
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 2 Mar 89  00:08:35 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA09450; Thu, 2 Mar 89 00:06:40 PST
Message-Id: <8903020806.AA09450@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
	for x3j13@sail.stanford.edu; id AA09450; Thu, 2 Mar 89 00:06:40 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 2 Mar 89 03:05
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: Section 2.2 - part 3

%%Types - part 3
 
\beginsubsubsection{\datatype Null} 
 
The  only {\word object} of type {\datatype null\/} is @nil\rm.
 
 
\beginsubsubsection{\datatype Sequence} 
             
The type {\datatype sequence} has 
{\datatype vector} and {\datatype list}
as {\word disjoint subtypes}.
An {\word object} of type {\datatype sequence\/} is called a {\datatype
sequence}.
 
 
Figure {\chapno--\the\capno} lists the {\datatype sequence} {\word tools}.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt elt }&{\tt  subseq }&{\tt  copy-seq }\cr
{\tt length }&{\tt  reverse }&{\tt  nreverse }\cr
{\tt make-sequence }&{\tt  concatenate }&{\tt  map }\cr
{\tt some }&{\tt  every }&{\tt  notany }\cr
{\tt notevery }&{\tt  reduce }&{\tt  fill }\cr
{\tt replace }&{\tt  remove }&{\tt  remove-if }\cr
{\tt remove-if-not }&{\tt  delete }&{\tt  delete-if }\cr
{\tt delete-if-not }&{\tt  remove-duplicates }&{\tt  delete-duplicates }\cr
{\tt substitute }&{\tt  substitute-if }&{\tt  substitute-if-not }\cr
{\tt nsubstitute }&{\tt  nsubstitute-if }&{\tt  nsubstitute-if-not }\cr
{\tt find }&{\tt  find-if }&{\tt  find-if-not }\cr
{\tt position }&{\tt  position-if }&{\tt  position-if-not }\cr
{\tt count }&{\tt  count-if }&{\tt  count-if-not }\cr
{\tt mismatch }&{\tt  search }&{\tt  sort }\cr
{\tt stable-sort }&{\tt  merge }&\cr
\noalign{\vskip -9pt} }} 
\caption{Sequence tools}
\endfig
 
%% 14.0.0 19
 
Whenever a {\datatype sequence} function must construct and return
a new {\datatype vector}, it always returns a {\datatype simple-vector}.
In particular, any {\datatype strings} constructed 
will be {\datatype simple-strings}.
 
 
%% 2.5.1 1
\beginsubsubsection{\datatype Vector} 
 
The type {\datatype vector} has {\word subtypes} {\datatype simple-vector,
string}, and {\datatype bit-vector}. 
An {\word object} of type {\datatype vector} 
(a {\datatype vector}) is a 
one-dimensional {\datatype array\/}. 
 
\beginsubsubsection{\datatype Simple-vector} 
 
An {\word object} of type {\datatype simple-vector} 
(a {\datatype simple-vector}) is
a {\datatype vector} 
that is not displaced to another {\datatype vector},
has no 
{\word fill pointer}, 
is able to hold elements of any {\word type},
and is not to have its size adjusted dynamically after
creation.                                 
 
\beginsubsubsection{\datatype Bit-vector} 
 
An {\word object} of type {\datatype bit-vector} 
(a {\datatype bit-vector})
is a
{\datatype vector} composed of bits.
The type {\datatype bit-vector} has the type {\datatype simple-bit-vector}
as its {\word subtype}.
 
\beginsubsubsection{\datatype Simple-bit-vector} 
 
An {\word object} of type {\datatype simple-bit-vector} 
(a {\datatype simple-bit-vector}) is
a {\datatype bit-vector} that is not displaced to another 
{\datatype bit-vector},
has no {\word fill pointer}, 
and is not to have its size adjusted dynamically after
creation.                                 
 
 
%% 2.5.2 1
%% 18.0.0 3
\beginsubsubsection{\datatype String} 
 
An {\word object} of type {\datatype string} 
(a {\datatype string}) is
a {\datatype vector} whose
elements are {\datatype string-chars\/}. 
{\datatype Simple-string} is a {\word subtype} of {\datatype string}.
 
Figure {\chapno--\the\capno} 
lists the {\word tools} that are applicable to {\datatype strings}.
The following rules apply to {\datatype strings} and {\datatype string}
operations:
 
\beginlist
%% 18.0.0 7
\itemitem{--}
{\datatype Strings} may have {\word fill pointers}.
 
%% 18.0.0 4
\itemitem{--}
An {\word operator} 
that uses the print name of an argument provided as a 
{\datatype symbol} (most of
the operators in Figure {\chapno--\the\capno}) 
is not allowed to modify that {\datatype 
symbol}.
 
%% 18.0.0 5
%% paragraph duplicated in descriptions of string-equal and string=
%% 18.0.0 6
%% paragraph duplicated in description of stringp
 
\endlist
 
 
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt char }&{\tt schar }&{\tt string= }\cr
{\tt string-equal }&{\tt string< }&{\tt string> }\cr
{\tt string<= }&{\tt string>= }&{\tt string/= }\cr
{\tt string-lessp }&{\tt string-greaterp }&{\tt string-not-greaterp }\cr
{\tt string-not-lessp }&{\tt string-not-equal }&{\tt make-string }\cr
{\tt string-trim }&{\tt string-left-trim }&{\tt string-right-trim }\cr
{\tt string-upcase }&{\tt string-downcase }&{\tt string-capitalize }\cr
{\tt nstring-upcase }&{\tt nstring-downcase }&{\tt nstring-capitalize }\cr
{\tt string }& & \cr
 
\noalign{\vskip -9pt} }} 
\caption{String tools}  
\endfig
 
 
\beginsubsubsection{\datatype Simple-string} 
 
An {\word object} of type {\datatype simple-string} 
(a {\datatype simple-string}) is
a {\datatype string} that is not displaced to another {\datatype string},
has no {\word fill pointer}, and is not to have its size adjusted 
dynamically after
creation.                                 
 
 
%% 2.4.0 2
%% 2.4.0 7
\beginsubsubsection{\datatype List} 
 
The type {\datatype list} is
composed of {\word subtypes}
{\datatype cons} and {\datatype null}, which form an 
{\word exhaustive partition}
of {\datatype list}. 
An {\word object} of type {\datatype list} 
(a {\datatype list}) 
is a chain of {\datatype conses} 
linked by their {\word cdr} components
and terminated by @nil, the empty {\datatype list}. 
The {\word car} components of the {\datatype conses}
are called the elements of the {\datatype list}.  
For each element of the {\datatype list}
there is a {\datatype cons}.  The empty {\datatype list} 
has no elements at all.
 
A {\word dotted list} 
is a chain of {\datatype conses} 
linked by their {\word cdr} components
and not terminated by @nil.
Unless otherwise specified in this
standard, it is an error to pass a {\word dotted
list} to a {\word function} 
that is specified to require a {\datatype list} as an argument.
The following figures contain lists of {\word tools} that are applicable to {\datatype
lists}.
 
Figure {\chapno--\the\capno} lists the {\datatype cons} 
and {\datatype list} operation {\word tools}.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt car }&{\tt  cdr }&{\tt  caar }\cr
{\tt cadr }&{\tt  cdar }&{\tt  cddr }\cr
{\tt caaar }&{\tt  caadr }&{\tt  cadar }\cr
{\tt caddr }&{\tt  cdaar }&{\tt  cdadr }\cr
{\tt cddar }&{\tt  cdddr }&{\tt  caaaar }\cr
{\tt caaadr }&{\tt  caadar }&{\tt  caaddr }\cr
{\tt cadaar }&{\tt  cadadr }&{\tt  caddar }\cr
{\tt cadddr }&{\tt  cdaaar }&{\tt  cdaadr }\cr
{\tt cdadar }&{\tt  cdaddr }&{\tt  cddaar }\cr
{\tt cddadr }&{\tt  cdddar }&{\tt  cddddr }\cr
{\tt cons }&{\tt  tree-equal }&{\tt  endp }\cr
{\tt list-length }&{\tt  nth }&{\tt  first }\cr
{\tt second }&{\tt  third }&{\tt  fourth }\cr
{\tt fifth }&{\tt  sixth }&{\tt  seventh }\cr
{\tt eighth }&{\tt  ninth }&{\tt  tenth }\cr
{\tt rest }&{\tt  nthcdr }&{\tt  last }\cr
{\tt list }&{\tt   list* } & {\tt  make-list }\cr 
{\tt  append } & {\tt copy-list }&{\tt  copy-alist }\cr
{\tt  copy-tree }& {\tt revappend }&{\tt  nconc }\cr
{\tt  nreconc }& {\tt push }&{\tt  pushnew }\cr
{\tt  pop }& {\tt butlast }&{\tt  nbutlast }\cr
{\tt  ldiff } & &\cr
\noalign{\vskip -9pt} }}
\caption{List tools - 1}
\endfig
 
 
Figure {\chapno--\the\capno} lists the 
{\datatype list} structure alteration and expression substitution {\word
tools}.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt rplaca }&{\tt  rplacd }&{\tt  subst }\cr
{\tt subst-if }&{\tt  subst-if-not }&{\tt  nsubst }\cr
{\tt nsubst-if }&{\tt  nsubst-if-not }&{\tt  sublis }\cr
{\tt nsublis }& & \cr
\noalign{\vskip -9pt} }}
\caption{List tools - 2}
\endfig
 
 
 
 
Figure {\chapno--\the\capno} lists the set 
operation and association list {\word tools}.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt  member }&{\tt  member-if } & {\tt member-if-not }\cr
{\tt  tailp }&{\tt  adjoin }& {\tt union }\cr
{\tt  nunion }&{\tt  intersection }& {\tt nintersection }\cr
{\tt  set-difference }&{\tt  nset-difference }& {\tt set-exclusive-or }\cr
{\tt  nset-exclusive-or }&{\tt  subsetp }& {\tt acons }\cr
{\tt  pairlis }&{\tt  assoc }& {\tt assoc-if }\cr
{\tt  assoc-if-not }&{\tt  rassoc }& {\tt rassoc-if }\cr
{\tt  rassoc-if-not }&&\cr
\noalign{\vskip -9pt} }}
\caption{List tools - 3}
\endfig
\goodbreak
Following are examples of printed representations of {\datatype lists}:
 
\screen!
 (a . b)    ;A dotted pair of a and b
 (a.b)      ;A list of one element, the symbol named a.b
 (a. b)     ;A list of two elements a. and b
 (a .b)     ;A list of two elements a and .b
 (a b . c)  ;A dotted list of a and b with c at the end; two conses
 .iot       ;The symbol whose name is .iot
 (. b)      ;Illegal -- an error is signalled if an attempt is made to read 
            ;this syntax.
 (a .)      ;Illegal -- an error is signalled.
 (a .. b)   ;Illegal -- an error is signalled.
 (a . . b)  ;Illegal -- an error is signalled.
 (a b c ...);Illegal -- an error is signalled.
 (a @bsl\ . b)         ;A list of three elements a, ., and b
 (a @vert\ .@vert b)   ;A list of three elements a, ., and b
 (a @bsl\ ... b)       ;A list of three elements a, ..., and b
 (a @vert\ ...@vert b) ;A list of three elements a, ..., and b
\endscreen!
                                              
                       

∂01-Mar-89  2355	X3J13-mailer 	Section 2.2 - part 2 
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 1 Mar 89  23:55:24 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA08620; Wed, 1 Mar 89 23:53:21 PST
Message-Id: <8903020753.AA08620@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
	for x3j13@sail.stanford.edu; id AA08620; Wed, 1 Mar 89 23:53:21 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 2 Mar 89 02:51
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: Section 2.2 - part 2

 
%%Types - part 2
\beginsubsubsection{\datatype Ratio} 
 
An {\word object} of type {\datatype ratio\/} (a {\datatype ratio}) is the
mathematical ratio of two {\datatype integers}. 
 
%% 2.1.1 1
\beginsubsubsection{\datatype Integer} 
 
The type {\datatype integer} is composed of 
{\word disjoint} {\datatype
fixnum} and {\datatype bignum} subtypes. 
An {\word object} of type {\datatype integer\/} (an {\datatype integer}) is a 
mathematical integer. There is no limit on the magnitude of an 
{\datatype
integer}.
            
Properties of integers follow:
\beginlist 
\itemitem{--} 0 = $-0$
\itemitem{--} The default printed 
representation and interpretation for an {\datatype
integer} is decimal.
\endlist
 
%% 2.1.1 2
\beginsubsubsection{\datatype Fixnum} 
 
An {\word object} of type {\datatype fixnum} (a {\datatype fixnum}) is an 
an 
{\datatype integer} whose value is between 
{\function most-negative-fixnum} and
{\function most-positive-fixnum} inclusive.
Exactly which {\datatype integers} are
{\datatype fixnums} is implementation-dependent.
         
\beginsubsubsection{\datatype Bignum} 
 
An {\word object} of type {\datatype bignum} (a {\datatype bignum}) 
is an 
{\datatype integer} outside the {\datatype fixnum} range.
 
\beginsubsubsection{\datatype Float} 
 
The type {\datatype float} is composed of the
{\word disjoint} or identical {\datatype short-float}, 
{\datatype single-float},
{\datatype double-float}, and {\datatype long-float} subtypes.        
An {\word object} of type {\datatype float} (a {\datatype floating}-point
number) 
is a (mathematical)
{\datatype rational} of the form
{\it s@centerdot f@centerdot $b↑{e-p}$},
where {\it s} is +1 or @minussign 1, the {\it sign}\rm;
{\it b} is an {\datatype integer} 
greater than 1, the {\it base} or {\it radix} of the representation;
{\it p} is a positive {\datatype integer}, 
the {\it precision} (in base-{\it b} digits) of the floating-point {\datatype
number};
{\it f} is a positive {\datatype integer} 
between {\it $b↑{p-1}$} and
{\it $b↑p-1$} (inclusive), the significand;
and {\it e} is an {\datatype integer}, the exponent.
The value of {\it p} and the range of {\it e}
depends on the implementation and on the type of {\datatype floating-point} number
within that implementation.
An {\word object} of type {\datatype short-float\/} is called a {\datatype
short-float}.
An {\word object} of type {\datatype single-float\/} is called a {\datatype
single-float}.
An {\word object} of type {\datatype double-float\/} is called a {\datatype
double-float}.
An {\word object} of type {\datatype long-float\/} is called a {\datatype
long-float}.
 
 
Properties of {\datatype floating-point} numbers follow:
                
\beginlist
\itemitem{--} There is a {\datatype floating-point} number
whose value is zero.   
\itemitem{--} If the numeric representation of 
{\datatype floating-point} numbers
allows ``minus zero'', it will exist.
\itemitem{--} {\tt $0.0$ = $-0.0$} if there is no minus zero.
\endlist
 
%% 2.1.3 6
Intermediate between {\datatype short-float} and {\datatype long-float}
are
{\datatype single-float} and {\datatype double-float}.
The precise definition of these categories is implementation-dependent.
The precision (measured in ``bits'', computed as {\it p} log$\sub 2${\it b}\rm)
and the exponent size (also measured in ``bits'', computed as
log$\sub 2$ (maximum exponent value + 1)) is recommended
to be at least as great
as the values in Figure {\chapno--\the\capno}. 
\boxfig          
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip 
\dimen0 plus .5 fil&#\hfil\cr 
\noalign{\vskip -9pt}
\hfil\bf Format &Minimum Precision &Minimum Exponent Size \cr
\noalign{\vskip 2pt\hrule\vskip 2pt}
Short&13 bits&5 bits\cr
Single&24 bits&8 bits\cr                             
Double&50 bits&8 bits\cr                         
Long&50 bits&8 bits\cr
\noalign{\vskip -9pt}
}}
\caption{Recommended Minimum Floating-Point Precision and Exponent Size}
\endfig
 
%% 2.1.3 10
%% 2.1.3 11
%% 2.1.3 18
There may be fewer than four internal 
representations for {\datatype floating-point} numbers.
If there are fewer distinct representations, the following fules apply:
\beginlist
\itemitem{--} If there is only one, it is of
the type {\datatype single-float}.
In this representation, an {\word object} is simultaneously of types 
{\datatype single-float, double-float, short-float}, and {\datatype
long-float}.
\itemitem{--} Two internal representations can be arranged in either of the
following ways:
\beginlist
\itemitem{\bull} Two {\word types} are provided: {\datatype single-float} and
{\datatype short-float}. An {\word object} is simultaneously of types
{\datatype single-float, double-float}, and {\datatype long-float}.
\itemitem{\bull} Two {\word types} are provided: {\datatype single-float} and
{\datatype double-float}. An {\word object} is simultaneously of types
{\datatype single-float} and {\datatype short-float}, or
{\datatype double-float} and {\datatype long-float}.
\endlist
\itemitem{--} Three internal representations can be arranged in either
of the following ways:
\beginlist
\itemitem{\bull} Three {\word types} are provided: {\datatype short-float}, 
{\datatype single-float}, and 
{\datatype double-float}. An {\word object} can
simultaneously be of type {\datatype double-float} and {\datatype long-float}.
\itemitem{\bull} Three {\word types} are provided: 
{\datatype single-float}, {\datatype double-float},
and {\datatype long-float}. An {\word object} can simultaneously
be of types {\datatype single-float} and {\datatype short-float}.
\endlist
\endlist          
 
Figure {\chapno--\the\capno} contains
examples of printed {\datatype floating-point} numbers:
The following rules apply to floating point computations.
 
%% 12.1.0 1
%% 12.5.0 3
\beginlist
\itemitem{--} 
Computations with {\datatype floating-point} numbers are only approximate,
although they are described as if the results
were mathematically accurate. 
Two mathematically identical
expressions may be computationally different because of errors
inherent in the floating-point approximation process.
The precision of a {\datatype floating-point} number is not necessarily
correlated with the accuracy of that number.
For instance, 3.142857142857142857 is a more precise approximation
to $\pi$ than 3.14159, but the latter is more accurate.
The precision refers to the number of bits retained in the representation.
When an operation combines a {\datatype short-float} with a 
{\datatype long-float},
the result will be a {\datatype long-float}. 
@clisp\ {\word functions} assume that the accuracy of
arguments to them does not exceed their precision.  Therefore
when two small {\datatype floating-point} numbers
are combined, the result is a small {\datatype floating-point} number.
@clisp\ {\word functions} 
never convert automatically from a larger size to a smaller one.
 
 
%% 12.1.0 2
\itemitem{--} An error of type {\datatype floating-point-overflow}
or {\datatype floating-point-underflow} should be signalled if a 
floating-point computation causes exponent overflow or underflow.
 
%% 12.1.0 5
\itemitem{--} 
The result of a numerical function
is a {\datatype floating-point} number of the largest format among all the
floating-point arguments to the {\word function}. 
\endlist
 
                                   
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip 
\dimen0 plus .5 fil&#\hfil\cr 
\noalign{\vskip -9pt}
{\tt 0.0}  				& ;Floating-point zero in default format
\cr
{\tt 0E0 }				& ;Also floating-point zero in default format
\cr
{\tt -.0 }				& ;This may be a zero or a minus zero, \cr
				& ; depending on the implementation \cr
{\tt 0.}				& ;The integer zero, not a floating-point
number! \cr
{\tt 0.0s0 }				& ;A floating-point zero in short format
\cr
{\tt 0s0 }				& ;Also a floating-point zero in short format
\cr
{\tt 6.02E+23}			& ;Avogadro's number, in default format
\cr
{\tt 602E+21}				& ;Also Avogadro's number, in default format
\cr
%3.010299957f-1			& ;$log_10$2, in single format \cr
}}
\caption{Examples of Floating-point numbers}
\endfig
 
%% 2.1.4 1
%% 2.1.4 4
\beginsubsubsection{\datatype Complex} 
 
An {\word object} of type {\datatype complex\/} (a {\datatype complex\/} number)
is represented in Cartesian form, with a real part and an imaginary
part each of which is not a 
{\datatype complex\/} number
(i.e. an {\datatype integer}, {\datatype ratio}, or {\datatype floating-point}
number).  The parts of a {\datatype complex\/} number
are not necessarily {\datatype floating-point} numbers
but both parts must
be of the same {\word type}: either both are 
{\datatype rationals}, or both are 
of the same {\datatype floating-point} number  {\word subtype}.
When constructing 
a {\datatype complex\/} number, if the specified parts are not the same 
{\word type}, the parts will be converted to be the same {\word type}
internally (i.e. the {\datatype rational} part
will be converted to
a {\datatype floating-point} number).
An {\word object} of type                 
{\tt (complex rational)} 
will be converted internally and represented thereafter as
a {\datatype rational} 
if its imaginary part is an 
{\datatype integer} whose value is 0.
 
%% 12.1.0 6
The following rules apply to {\datatype complex\/} computations:
 
\beginlist
\itemitem{--} 
Except during the execution of irrational and
transcendental {\word forms}, {\datatype complex\/} 
numbers never result from a numerical {\word form}
unless one or more of the
arguments is {\datatype complex\/}.  
 
\itemitem{--} 
When a non-{\datatype complex\/} number and 
a {\datatype complex\/} number are both part of a computation, 
the non-{\datatype complex\/}
number is first converted to a {\datatype complex\/} number by providing an
imaginary part of @f[0]\rm.
 
%% 12.1.0 8
 
\itemitem{--}
If the result of any computation would be a {\datatype complex\/}
number whose real part is  of type {\datatype rational} and whose imaginary
part is zero, the result is 
converted to a non-{\datatype complex\/} number
of type {\datatype rational} composed of the
real part.  
This rule does not apply to {\datatype complex\/} numbers whose parts
are {\datatype floating-point} numbers.  
For example, @f[\#C(5 0)] and @f[5] are not
distinct values in @clisp\ (they are always {\function eql});
@f[\#C(5.0 0.0)] and @f[5.0] are always distinct values in @clisp\
(they are never {\function eql}, although they are {\function equalp}).
\endlist
 
%% 12.5.3 17
Figure {\chapno--\the\capno} lists
the identities that are obeyed
throughout the applicable portion of the complex domain, even on
the branch cuts:
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 
plus 1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
sin i z = i sinh z & sinh i z = i sin z& arctan i z = i arctanh z \cr
cos i z = cosh z & cosh i z = cos z & arcsinhi z = i arcsin z \cr
tan i z = i tanh z & arcsin i z = i arcsinh z & arctanh i z = i arctan z \cr
\noalign{\vskip -9pt}
}}
\caption{Trigonometric Identities for Complex Domain}
\endfig
    
 
 
%% 2.2.4 1
\beginsubsubsection{\datatype Character} 
 
The type {\datatype character} has a 
{\word subtype}
of {\datatype string-char}.
An {\word object} of type {\datatype character} (a {\datatype character})
has three non-negative attributes: code, bits, and font.
 
%% 13.0.0 3
%% 13.0.0 4
The following rules apply to {\datatype characters}:
\beginlist
\itemitem{--} Two {\datatype characters} 
that are {\function eql}, {\function char=}, or {\function char-equal} 
are not necessarily {\function eq}.
 
%% 13.1.0 1
\itemitem{--} Every {\datatype character} 
has three attributes: code, bits, and font.
The code attribute is intended to distinguish among the printed glyphs
and formatting functions for {\datatype characters}.
The bits attribute allows extra
flags to be associated with a {\datatype character}.  The font attribute permits
a specification of the style of the glyphs (such as italics).
Each of these attributes is a non-negative 
{\datatype integer}.
 
%% 13.5.0 1
\itemitem{--} Four bits of the bits attribute are defined:
Control, Meta, Hyper, and Super.  
Each @clisp\ implementation provides these bit definitions for compatibility,
even if it does not support the bits.
 
\itemitem{--} The total ordering on 
{\datatype characters} is guaranteed to have the following
properties: 
 
\beginlist
%% 13.2.0 27
\itemitem{\bull} If two {\datatype characters} 
have the same bits and font attributes,
then their ordering by {\function char<} is consistent with the numerical
ordering by the predicate {\function <} on their code attributes.
 
%% 13.2.0 28
\itemitem{\bull} If two {\datatype characters} 
differ in any attribute (code, bits, or font), then they
are different.
 
%% 13.2.0 29
\itemitem{\bull} The total ordering is not necessarily the same as the total
ordering on the {\datatype integers} 
produced by applying @Funref[char-int] to the
{\datatype characters}.
 
%% 13.2.0 30
\itemitem{\bull} 
While alphabetic {\datatype characters} of a given case must be   
properly ordered, they need not be contiguous; it is permitted for 
uppercase and lowercase letters to be interleaved. 
Thus @f[(char<= \#{\char '134}a x
\#{\char '134}z)] is not 
a valid way of determining whether or not @f[x] is a
lowercase letter.  
 
 
%% 13.2.0 34
\itemitem{\bull} 
The ordering may depend on the font information. For example, an implementation
might decree that {\tt (char-equal \#{\char '134}p \#{\char '134}{\it p})}
be true, but that
{\tt (char-equal \#{\char '134}p \#{\char '134}$\pi$)}
be false (where {\tt \#{\char '134}$\pi$} is a
lowercase @f[p] in some font).  Assuming italics to be in font 1
and the Greek alphabet in font 2, this is the same as saying that
{\tt (char-equal \#0{\char '134}p \#1{\char '134}p)} 
may be true and at the same time
{\tt (char-equal \#0{\char '134}p \#2{\char '134}p)} may be false.
\endlist
 
%% 13.2.0 25
%% 13.2.0 26
The standard alphanumeric characters obey the following partial ordering:
 
@Lisp
 A<B<C<D<E<F<G<H<I<J<K<L<M<N<O<P<Q<R<S<T<U<V<W<X<Y<Z
 a<b<c<d<e<f<g<h<i<j<k<l<m<n<o<p<q<r<s<t<u<v<w<x<y<z
 0<1<2<3<4<5<6<7<8<9
 either 9<A or Z<0
 either 9<a or z<0                                                      
@Endlisp
This implies that alphabetic ordering holds within each case (upper and
lower), and that the digits as a group
are not interleaved with letters.  However, the ordering
or possible interleaving of
uppercase letters and lowercase letters is unspecified.
The following figures contain lists of {\word tools} applicable to {\datatype
characters}.
 
 
 
 
 
Figure {\chapno--\the\capno} lists the {\datatype character} 
attribute and predicate {\word tools}.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt char-code-limit }&{\tt  char-font-limit }&{\tt  char-bits-limit }\cr
{\tt standard-char-p }&{\tt  graphic-char-p }&{\tt  string-char-p }\cr
{\tt alpha-char-p }&{\tt  upper-case-p }&{\tt  lower-case-p }\cr
{\tt both-case-p }&{\tt  digit-char-p }&{\tt  alphanumericp }\cr
{\tt char= }&{\tt  char/= }&{\tt  char< }\cr
{\tt char> }&{\tt  char<= }&{\tt  char>= }\cr
{\tt char-equal }&{\tt  char-not-equal }&{\tt  char-lessp }\cr
{\tt char-greaterp }&{\tt  char-not-greaterp }&{\tt  char-not-lessp }\cr
\noalign{\vskip -9pt} }} 
\caption{Character tools - 1}
\endfig
 
 
Figure {\chapno--\the\capno} lists the 
{\datatype character} construction, conversion, and control-bit {\word tools}.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt char-code }&{\tt  char-bits }&{\tt  char-font }\cr
{\tt code-char }&{\tt  make-char }&{\tt  character }\cr
{\tt char-upcase }&{\tt  char-downcase }&{\tt  digit-char }\cr
{\tt char-int }&{\tt  int-char }&{\tt  char-name }\cr
{\tt name-char }&{\tt  char-control-bit }&{\tt  char-meta-bit }\cr
{\tt char-super-bit }&{\tt  char-hyper-bit }&{\tt  char-bit }\cr
{\tt set-char-bit }& & \cr
\noalign{\vskip -9pt} }} 
\caption{Character tools - 2}
\endfig
 
%% 2.2.5 1
\beginsubsubsection{\datatype String-char} 
 
The type {\datatype string-char} has a {\word subtype} of {\datatype 
standard-char}.             
An {\word object} of type {\datatype string-char} (a {\datatype string-char})
is a {\datatype character\/} whose bit and font
attributes are {\datatype integers} 
whose values are 0.
 
\beginsubsubsection{\datatype Standard-char} 
 
{\word Objects} of type {\datatype standard-char} ({\datatype standard-chars})
are listed 
in ``Object Syntax''.
 
%% 2.3.0 1
%% 2.3.0 2
\beginsubsubsection{\datatype Symbol} 
 
An {\word object} of type {\datatype symbol} (a {\datatype symbol})
is a data structure
composed of a print namestring, 
a package name, and a
property list. A {\datatype symbol} may be retrieved from 
a {\datatype package} given a print name.
{\datatype Symbols} can be interned or uninterned in a {\datatype package}.
 
%% 11.0.0 11
To intern a {\datatype symbol} in a {\datatype package} means to cause the
{\datatype symbol} 
to be accessible in the {\datatype package} if it were not already.
See {\function intern}.
If the {\datatype symbol} were previously unowned, then the 
{\datatype package} it is being
interned in becomes its owner (home package); but
if the {\datatype symbol} 
was previously owned by another {\datatype package}, that other {\datatype
package}
continues to own the {\datatype symbol}.
 
%% 10.3.0 2
%% 10.3.0 3                                
Interned symbols are created automatically by {\function intern}; 
If a given print name does not have a corresponding 
{\datatype symbol} in the specified or
inherited {\datatype packages}, a {\datatype symbol} is 
created for that print name.
the first time
something (such as {\function read})
asks the package system for a {\datatype symbol} with a given print name,
that {\datatype symbol} is automatically created.  
 
 
%% 11.0.0 12
To unintern a {\datatype symbol} from a
{\datatype package} means to cause it to be not
present and, additionally, to make the {\datatype symbol} uninterned if the
{\datatype package} is the {\datatype symbol's} home package.
See @Funref[unintern]\rm.
 
 
%% 10.3.0 1
{\datatype Symbols} have the following 
components, the first three of which are user-visible.
 
%% 10.0.0 3
%% 10.0.0 4
%% 10.1.0 1
%% 10.1.0 2
%% 10.1.0 3
\beginlist
\itemitem{\bf Property list} 
 
The property list is an even-length 
{\datatype list} of zero or more
elements
whose even-numbered components (calling the first component zero) 
are indicators (no duplicates on the same
property list are allowed)
and whose odd-numbered components are {\word objects}.
The property list of a {\datatype symbol}
may be destructively replaced.
A property-value pair in the property list may be added or updated.
%% 10.1.0 4
When a {\datatype symbol} is created, its property list is initially empty.
Properties are created by using {\function setf} of @Macref[get]\rm.
Any form acceptable to {\function setf\/}
as a {\word 
generalized reference} can be used to store the property list.
 
 
%% 10.0.0 5
%% 10.2.0 1
\itemitem{\bf Print name} 
 
The print name is a {\datatype string}, 
used to identify the {\datatype symbol}.
Every 
{\datatype symbol} has a print name, and that
name can not be altered.
The print name is used as the external representation of the 
{\datatype symbol}.
If the {\datatype characters} in the {\datatype string} 
of the print name are typed in to {\function read}
(with suitable escape conventions for certain characters),
it is interpreted as a reference to that {\datatype symbol}
(if it is {\word interned}); and if the {\datatype symbol} 
is printed, {\function print} outputs the
print name.
Given the print name of a {\datatype symbol} 
as a {\datatype string} the 
{\datatype symbol} can be obtained.  
Every time a {\datatype symbol} with a certain print name is referenced,
the same ({\function eq}) {\datatype symbol } is returned.
{\datatype Symbols} are organized into
{\datatype packages}, and all the {\datatype symbols} 
in a {\datatype package} are uniquely
identified by print name.  
 
A {\datatype symbol\/}'s print name can be composed
of any {\datatype string-char}. Space and parenthesis characters
must be preceded by an
escape character in order to be a part of a {\datatype symbol\/}'s print name.
A {\datatype symbol\/}'s print name must contain escape characters if 
 
 
\beginlist
\itemitem{\bull} It would be composed of only periods
(.).
\itemitem{\bull} It would be syntactically identical to a 
{\datatype number}.
\endlist
Any double quote in the name
of a {\datatype symbol} written using vertical-bar notation need not be
preceded by a @bsl.  
 
%% 10.0.0 4
%% 10.3.0 4
%% 11.0.0 8
%% 11.0.0 10
%% 11.0.0 28
\itemitem{Package cell} 
 
The package cell 
contains a pointer to the {\datatype symbol's} 
home {\datatype package}, if
it is interned in and owned by any {\datatype package}, 
or @false\ if it is uninterned (not owned by a {\datatype package}).
The package cell 
may be accessed by @Funref[symbol-package]\rm.
 
A {\datatype symbol} may
appear in many {\datatype packages}, but it can have at most
one home {\datatype package}.
The same print name may refer to different {\datatype symbols} in
different {\datatype packages}.
 
%% 10.0.0 8
\itemitem{Other components} 
 
A {\datatype symbol} may have other components for use by the
implementation.  
\endlist
 
Following is the list of 
{\word tools} that are applicable to the property list of
{\datatype symbols}: {\tt  get}, {\tt  remprop},
{\tt symbol-plist}, {\tt  getf}, {\tt  remf}, and 
{\tt get-properties}.
The function {\tt symbol-name} is used to access the print name of 
a symbol.
Following is the list of 
{\word tools} that are applicable to creating
{\datatype symbols}: {\tt make-symbol}, {\tt  copy-symbol},
{\tt gensym}, {\tt  gentemp}, {\tt  symbol-package}, and 
{\tt keywordp}.
 

∂02-Mar-89  0834	X3J13-mailer 	Section 2.2 - part 4 
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 2 Mar 89  08:33:46 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA02028; Thu, 2 Mar 89 08:31:42 PST
Message-Id: <8903021631.AA02028@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
	for x3j13@sail.stanford.edu; id AA02028; Thu, 2 Mar 89 08:31:42 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 2 Mar 89 07:40
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: Section 2.2 - part 4

%%Types - part 4
   
\beginsubsubsection{\datatype Cons} 
 
An {\word object} of type {\datatype cons} 
is called a {\word cons}.
 
%% 2.5.0 1
\beginsubsubsection{\datatype Array\/} 
 
The type {\datatype array\/} has {\word subtypes} {\datatype vector}
and {\datatype simple-array}.
An {\word object} of type {\datatype array\/} 
(an {\datatype array\/}) 
contains {\word objects} arranged according
to a Cartesian coordinate system.
 
 
%% 17.0.0 3
The following rules apply to {\datatype arrays\/}.
 
\beginlist
\itemitem{--} An {\datatype array\/} contains components arranged according
to a rectilinear coordinate system.
%% 17.0.0 4
An {\datatype array\/} 
may be a general {\datatype array\/}, meaning each element may be any @xlisp\
{\word object}, or it may be a specialized {\datatype array\/}, 
meaning that each element
must be of a restricted {\word type}.
 
%% 2.5.0 3
%% 2.5.0 4
\itemitem{--}
In principle, an                                             
{\datatype array\/} in @clisp\ may have any number of dimensions, including zero.
It is permissible for a dimension to be zero, in which case
the {\datatype array\/} 
has no elements, and any attempt to access an element
is an error.  However, other properties of the {\datatype array\/}, 
such as the
dimensions themselves, may be used.
If the rank is zero, then there are no dimensions, and the
product of the dimensions is then by definition 1.
A zero-rank {\datatype array\/} therefore has a single element.
 
\itemitem{--} An implementation of may impose a limit on the rank of an 
{\datatype array\/},
but this limit may not be smaller than 7.  
The value of @conref[array-rank-limit] is the implementation's limit on 
{\datatype array\/} rank.
 
 
\itemitem{--}Each dimension is a non-negative 
{\datatype integer}; if any dimension of an {\datatype array\/} is zero,
the {\datatype array\/} has no elements.
 
%% 17.0.0 5
\itemitem{--}
General {\datatype vectors} may contain
any @xlisp\ {\word object}.  {\datatype Vectors} 
whose elements are restricted to type
{\datatype string-char} are called {\datatype strings}.
{\datatype Vectors} whose elements are
restricted to type {\datatype bit} are called {\datatype bit-vectors}.
 
%% 17.5.0 4
\itemitem{--}
Only {\datatype vectors} may have {\word fill pointers};
multidimensional {\datatype arrays\/} may not.  
A multidimensional {\datatype array\/} 
that is displaced to a {\datatype vector} that has
a {\word fill pointer} can be created.
 
%% 2.5.0 8
\itemitem{--}
Multidimensional {\datatype arrays\/} 
store their components in row-major order;
that is, internally a multidimensional {\datatype array\/} 
is stored as a one-dimensional
{\datatype array\/}, 
with the multidimensional index sets ordered lexicographically,
last index varying fastest.  
 
%% 2.5.0 5
\itemitem{--}
An {\datatype array\/} element is specified by a series of indices.
The length of the series must equal the rank of the {\datatype array\/}.
Each index must be a non-negative {\datatype integer} strictly less than
the corresponding {\datatype array\/} dimension.  {\datatype Array\/} 
indexing is zero-origin.
 
\itemitem{--}
%% 17.1.0 13
When an array A is given as
the @Kwd[displaced-to] argument to {\function make-array} 
when creating array B,
then array B is said to be displaced to array A.  The
total number of elements in an {\datatype array\/}, 
called the total size of the {\datatype array\/},
is calculated as the product of all the dimensions.
It is required that the total size of A be no smaller than the sum
of the total size of B plus the offset @f[n] supplied by
the @Kwd[displaced-index-offset]
argument.  The effect of displacing is that array B does not have any
elements of its own, but instead maps accesses to itself into
accesses to array A.  The mapping treats both {\datatype arrays\/} as if they
were one-dimensional by taking the elements in row-major order,
and then maps an access to element @f[k] of array B to an access to element
@f[k]+@f[n] of array A.
 
 
\itemitem{--}
When {\keyword displaced-to} is supplied to {\function make-array},
{\keyword displaced-index-offset} is made to be the
index offset of the \array.
If {\keyword displaced-index-offset} is not supplied,
the index offset is zero.
 
\endlist
The following figures contain lists of {\word tools} that are applicable to {\datatype
arrays}.
 
 
Figure {\chapno--\the\capno} lists the {\datatype array\/} 
creation, access, and information {\word tools}.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt make-array }&{\tt  array-rank-limit }&{\tt  array-dimension-limit }\cr
{\tt array-total-size-limit }&{\tt  vector }&{\tt  aref }\cr
{\tt svref }&{\tt  array-element-type }&{\tt  array-rank }\cr
{\tt array-dimension }&{\tt  array-dimensions }&{\tt  array-total-size }\cr
{\tt array-in-bounds-p }&{\tt  array-row-major-index }&{\tt  adjustable-array-p }\cr
{\tt upgraded-array-element-type} & {\tt upgraded-complex-part-type}  & \cr
\noalign{\vskip -9pt} }}
\caption{Array tools - 1}  
\endfig
 
 
Figure {\chapno--\the\capno} lists the {\word tools} 
for operations on {\datatype arrays} of bits.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt bit }&{\tt  sbit }&{\tt  bit-and }\cr
{\tt bit-ior }&{\tt  bit-xor }&{\tt  bit-eqv }\cr
{\tt bit-nand }&{\tt  bit-nor }&{\tt  bit-andc1 }\cr
{\tt bit-andc2 }&{\tt  bit-orc1 }&{\tt  bit-orc2 }\cr
{\tt bit-not }&&\cr
\noalign{\vskip -9pt} }}
\caption{Array tools - 2}  
\endfig
 
 
Figure {\chapno--\the\capno} lists 
the {\datatype array\/} {\word fill pointer} 
and dimension modification {\word tools}.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt  array-has-fill-pointer-p }&{\tt  fill-pointer }&{\tt vector-push}\cr 
{\tt vector-push-extend }&{\tt  vector-pop }&{\tt  adjust-array }\cr
\noalign{\vskip -9pt} }}
\caption{Array tools - 3}  
\endfig
 
 
%% 2.5.0 9
\beginsubsubsection{\datatype Simple-array} 
 
The type {\datatype simple-array\/}
has {\word subtypes} {\datatype
simple-vector}, {\datatype simple-string}, and {\datatype simple-bit-vector}.
An {\word object} of type {\datatype simple-array\/} 
(a {\datatype simple-array\/}) is
an {\datatype array\/} 
that is not displaced to another {\datatype array\/}, 
has no {\word fill pointer}, and
is not to have its size adjusted dynamically after 
creation.
 
 
%% 2.5.1 4
Implementations may provide certain specialized representations of
{\datatype arrays\/}
for efficiency in the case where all the components are of
the same specialized type.  
All implementations are required to provide specialized {\datatype arrays\/}
of bits, that is, {\datatype objects} of type {\tt (array bit)};
the one-dimensional instances of
this specialization are called {\datatype bit-vectors}.
All implementations
provide specialized {\datatype arrays\/}
for the cases when the components
are {\datatype characters} (or rather, 
a special subset of the {\datatype characters});
the one-dimensional instances of
this specialization are called {\datatype strings}.
           
 
%% 2.10.0 1
\beginsubsubsection{\datatype Stream} 
 
An {\word object} of type {\datatype stream} (a {\datatype stream}) 
is a source or sink of data.
 
%% 21.0.0 3
%% 21.0.0 4
For example, character {\datatype streams} 
produce or absorb {\datatype characters};
binary {\datatype streams} produce or absorb {\datatype integers}.
 
%% 21.0.0 3
A {\datatype stream}, whether a character stream or a binary
stream, may be input-only, output-only, or bidirectional.
What operations may be performed on a {\datatype stream} depends on which
type of {\datatype stream} it is.
 
%% 22.0.0 3
%All input/output operations are performed on {\datatype streams} 
%of various kinds.
The following figures contain lists of {\word tools} that are applicable to {\datatype
streams}.
 
 
Figure {\chapno--\the\capno} lists the standard {\datatype streams}.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
@var[standard-input] & @var[standard-output] & @var[error-output] \cr
@var[query-io] & @var[debug-io] & @var[terminal-io] \cr
@var[trace-output] & &\cr
\noalign{\vskip -9pt} }}
\caption{Stream tools - 1}  
\endfig
 
 
Figure {\chapno--\the\capno} lists the {\datatype stream} 
creation and manipulation {\word tools}.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr                         
\noalign{\vskip -9pt}                               
{\tt make-synonym-stream }&{\tt  make-broadcast-stream }\cr
{\tt  make-concatenated-stream} & {\tt make-two-way-stream }\cr
{\tt  make-echo-stream }&{\tt  make-string-input-stream }\cr
{\tt make-string-output-stream }&{\tt  get-output-stream-string }\cr
{\tt with-open-stream } & {\tt  with-input-from-string }\cr
{\tt  with-output-to-string }& {\tt streamp } \cr
{\tt  input-stream-p }&{\tt  output-stream-p }\cr
{\tt stream-element-type } & {\tt  close } \cr
\noalign{\vskip -9pt} }}
\caption{Stream tools - 2}  
\endfig
 
 
\beginsubsubsection{\datatype Hash-table} 
 
An {\word object} of type {\datatype hash-table} (a {\datatype hash-table}) 
contains keys and values.
 
%% 16.0.0 3                             
A {\datatype hash-table} maps a given
@xlisp\ {\word object} to another @xlisp\ {\word object} via a hash
mechanism.
Each {\datatype hash-table} 
has a set of entries, each of which associates a
key with a value.  
Figure {\chapno--\the\capno} lists the 
{\word tools} that are applicable to {\datatype hash-tables}.
The following rules apply to {\datatype hash-tables}.
 
%% 16.0.0 4
\beginlist
\itemitem{--}
A {\datatype hash-table} can only associate one value with a given
key. Adding a value to a {\datatype hash-table} is a destructive operation;
the {\datatype hash-table} is modified.  
 
%% 16.0.0 5
\itemitem{--}
There are three kinds of {\datatype hash-tables} -- those whose keys
are compared with {\function eq}, those whose keys
are compared with {\function eql}, and those whose keys
are compared with {\function equal}.  
 
%% 16.0.0 6
\itemitem{--}
{\datatype Hash-tables} are created by 
{\function make-hash-table}. 
{\function gethash} is used to look up a key and find
the associated value.
New entries are added
to {\datatype hash-tables} using @Macref[setf] with {\function gethash}.
{\function remhash} is used to remove an entry.
For example:
 
@Lisp
 (setq a (make-hash-table)) @EV #<Hash Table...>
 (setf (gethash 'color a) 'brown) @EV BROWN
 (setf (gethash 'name a) 'fred) @EV FRED
 (gethash 'color a) @EV BROWN T
 (gethash 'name a) @EV FRED T
 (gethash 'pointy a) @EV @false @false   
@Endlisp
 
%% 16.0.0 7             
In this example, the {\word symbols} @f[color] and @f[name] are being used as
keys, and the {\word symbols} @f[brown] and @f[fred] are being used as the
associated values.  The {\datatype hash-table} 
has two items in it, one of which                              
associates from @f[color] to @f[brown]\rm, and the other of which
associates from @f[name] to @f[fred]\rm.
 
%% 16.0.0 8
\itemitem{--}
A key or a value may be any {\word object}.
 
%% 16.0.0 9
\itemitem{--}
When a {\datatype hash-table} 
is first created, it has a size, which is the
maximum number of entries it can hold.  Usually the actual capacity of
the table is somewhat less, since the hashing is not perfectly
collision-free.  If so many entries are
added that the capacity is exceeded, the {\datatype hash-table} 
will automatically
grow, and the entries will be rehashed (new hash values will be
recomputed, and everything will be rearranged so that the fast hash
lookup still works).  This is transparent to the caller; it all happens
automatically.
 
%% 16.0.0 10
\itemitem{--}
The cases
of @f[nil] as a value and no entry in the {\datatype hash-table} 
can be distinguished by the second value returned by {\function gethash}.
\endlist               
 
 
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt make-hash-table }&{\tt  hash-table-p }&{\tt  gethash }\cr
{\tt remhash }&{\tt  maphash }&{\tt  clrhash }\cr
{\tt hash-table-count }&{\tt  sxhash }&\cr
\noalign{\vskip -9pt} }}
\caption{Hash-table tools}  
\endfig
 
%% 2.7.0 1
%% 22.1.5 2
\beginsubsubsection{\datatype Readtable} 
 
An {\word object} of type {\datatype readtable} (a {\datatype readtable}) 
maps {\datatype
characters\/} into syntax
types for the {\word Lisp reader} (see ``Character Reader'').
 
A {\datatype readtable} 
contains a macro
definition for 
each {\datatype character} with macro character syntax.
Figure {\chapno--\the\capno} lists the 
{\word tools} that are applicable to {\datatype readtables}.
See ``Object Syntax''.
 
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
@var[readtable] & {\tt copy-readtable} \cr
{\tt readtablep } & {\tt set-syntax-from-char }\cr
{\tt  set-macro-character }&{\tt  get-macro-character }\cr
{\tt make-dispatch-macro-character  }&{\tt  set-dispatch-macro-character }\cr
{\tt get-dispatch-macro-character} & \cr
\noalign{\vskip -9pt} }} 
\caption{Readtable tools}                              
\endfig
 
 

∂02-Mar-89  0930	X3J13-mailer 	cs proposal comments 
Received: from IBM.COM by SAIL.Stanford.EDU with TCP; 2 Mar 89  09:30:00 PST
Date: Thu, 02 Mar 89 02:27:38 PST
From: Thom Linden <baggins@IBM.com>
To: Common Lisp mailing <x3j13@sail.stanford.edu>
Message-ID: <890302.022738.baggins@almvma>
Subject: cs proposal comments

Just a reminder, please send comments/straw ballots to x3j13 and
not the characters mailing list.

Regards,
  Thom

∂02-Mar-89  0928	X3J13-mailer 	forwarding note from gregor from larry   
Received: from IBM.COM by SAIL.Stanford.EDU with TCP; 2 Mar 89  09:27:42 PST
Date: Wed, 01 Mar 89 13:15:48 PST
From: Thom Linden <baggins@IBM.com>
To: Common Lisp mailing <x3j13@sail.stanford.edu>
Message-ID: <890301.131548.baggins@almvma>
Subject: forwarding note from gregor from larry

=========================================================================
Received: from  Xerox.COM by ibm.COM on 02/23/89 at 10:00:35 PST
Received: from Semillon.ms by ArpaGateway.ms ; 23 FEB 89 09:56:23 PST
Date: Thu, 23 Feb 89 09:56 PST
From: Gregor.pa@Xerox.COM
Subject: [masinter.pa: Re: cs proposal straw vote]
To: baggins@IBM.com
Fcc: BD:>Gregor>mail>outgoing-mail-5.text.newest
Included-msgs: The message of 22 Feb 89 20:59 PST from masinter.pa
Included-References: The message of 22 Feb 89 12:08 PST from
 baggins@IBM.com
Message-ID: <19890223175611.1.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no


Larry asked me to forward this to you as the official Xerox position on
the straw ballot.

Date: Wed, 22 Feb 89 20:59 PST
From: masinter.pa

My personal opinion:

CHAR-FONT-UNUSED-CHAR-BITS-NONPORTABLE:
              Eliminate of font and bit attributes.
            **** Yes
          Add rules for an implementation supporting attributes.
            **** No. Attributes can be done as
                attributes of subclass of CHARACTER.
                Remove any description of
                implementation-supported attributes.
          Remove CHAR-FONT-LIMIT
          Remove CHAR-BITS-LIMIT
          Remove INT-CHAR
          Remove CHAR-BITS
          Remove CHAR-FONT
          Remove MAKE-CHAR
          Remove CHAR-CONTROL-BIT
          Remove CHAR-META-BIT
          Remove CHAR-SUPER-BIT
          Remove CHAR-HYPER-BIT
          Remove CHAR-BIT
          Remove SET-CHAR-BIT

        **** Yes.



Issue: CHAR-INT-ONLY-USEFUL-WHEN-ATTRIBUTES-SUPPORTED
Proposal:
          Remove CHAR-INT
**** YES

Issue: CHARACTER-TYPE-RESTRICTIVE
          Define BASE-CHARACTER as a subtype of STRING.
          Standard characters are a subset of the base
             characters.
          STANDARD-CHAR type is replaced by (CHARACTER :STANDARD)
          Remove the semi-standard characters.
**** NO.
    Define (CHARACTER :STANDARD) in the same
    way that STANDARD-CHAR used to be.
    Define BASE-CHARACTER as
    (upgraded-array-element-type '(CHARACTER :STANDARD)).
    Remove the semi-standard characters.
    <<You might argue that this has the same effect, but
    it doesn't.>>

Issue: STRING-TYPE-RESTRICTIVE
Proposal:
          Define STRING as a union type
        *** YES
          STRING used as a type specifier for object creation
             means (VECTOR CHARACTER)
        *** YES
          All string functions operate as specified on any
             string object except it is an error to insert
             an extended character into a base string.
        *** NO. It is an error to insert an object in an
        array where the object is not of the element type
        of the array.
        <<You might argue this has the same effect, but
        my wording here is more general.>>
          Extend the COERCE function to allow coercion from
            base string to extended string.
        *** NO. This is unnecesarry. COERCE already
        coerces from one vector type to another.

Issue: STRING-TYPE-ABBREVIATIONS
Proposal:
          Add BASE-STRING
          Add GENERAL-STRING
    *** NO. Unnecessary, confusing, clutter.

Issue: SIMPLE-STRING-TYPE-RESTRICTIVE
Proposal:
          Define SIMPLE-STRING as a union type
          Define SIMPLE-STRING as a type specifier for object
             creation means (SIMPLE-ARRAY CHARACTER (size))
    *** NO. Confusing. Poor performance model.
        SIMPLE isn't simple.

Issue: SIMPLE-STRING-TYPE-ABBREVIATIONS
Proposal:
          Add SIMPLE-BASE-STRING
          Add SIMPLE-GENERAL-STRING
    *** NO, even if SIMPLE-STRING-TYPE-RESTRICTIVE adopted.
        Unnecessary. Useless clutter.

Issue: FILE-EXTERNAL-REPRESENTATION
Proposal:
          Add :EXTERNAL-CODED-CHARACTER-FORMAT keyword to OPEN
    *** NO, wrong name. Unspecified. Better to omit than to
    add with unspecified or poorly specified behavior.
    Better to add as "future direction" in standard than in current
    state.

Issue: STRING-BINARY-WIDTH
Proposal:
          Add :EXTERNAL-CODED-STRING-LENGTH function
    *** NO, even if you meant to omit the :. CL currently doesn't
    admit that text and binary can be intermixed. No standard
    way to use information returned. No relation to
    FILE-POSITION defined.

Issue: CHAR-CODE-NON-PORTABLE
Proposal:
          Add CHAR-CCS-VALUE function
    *** NO. Requires lots of implementation mechanism.
    Of limited use in nearly all situations.

Issue: CHARACTER-IDENTIFICATION-NONPORTABLE
Proposal:
           Introduce the concept of Registries
        *** IF modified; should only suggest names of
        character repertoires, and name at least
        STANDARD HIRAGANA KATAKANA
        GREEK. Standardization of repertoire elements
        to be specified in future.
           Standardize on #\registry:id
        *** YES, as suggestion
      add all-implemented-registries
        *** NO
           Add *ALL-CHARACTER-REGISTRY-NAMES* variable
        *** NO
           Add FIND-CHAR function
        *** NO, NAME-CHAR will do
           Add CHAR-LABEL function
        *** NO, CHAR-NAME will do
           Add CHAR-REGISTRY-NAME function
        *** NO, string processing on CHAR-NAME will do
           New syntax for CHARACTER type specifier
        *** YES
           New #\label:registry character name syntax
        *** ??? This was already mentioned
           New argument to CHARACTERP
        *** YES.
-------

∂02-Mar-89  0928	X3J13-mailer 	forwarding mail from gray 
Received: from IBM.COM by SAIL.Stanford.EDU with TCP; 2 Mar 89  09:28:08 PST
Date: Wed, 01 Mar 89 15:59:07 PST
From: Thom Linden <baggins@IBM.com>
To: Common Lisp mailing <x3j13@sail.stanford.edu>
Message-ID: <890301.155907.baggins@almvma>
Subject: forwarding mail from gray

=========================================================================
Received: from  dsg.csc.ti.com by ibm.COM on 03/01/89 at 10:29:25 PST
Received: from ti.com by RELAY.CS.NET id aa05395; 28 Feb 89 23:18 EST
Received: by ti.com id AA00500; Tue, 28 Feb 89 22:18:18 CST
Received: from Kelvin by tilde id AA21544; Tue, 28 Feb 89 22:08:43 CST
Message-Id: <2813717283-5615057@Kelvin>
Sender: GRAY%kelvin.csc.ti.com@RELAY.CS.NET
Date: Tue, 28 Feb 89  22:08:03 CST
From: David N Gray <Gray%dsg.csc.ti.com@RELAY.CS.NET>
To: Thom Linden <baggins@IBM.COM>
Cc: CL-Characters@SAIL.STANFORD.EDU, Bartley%mips.csc.ti.com@RELAY.CS.NET,
    Waldrum%tilde.csc.ti.com@RELAY.CS.NET
Subject: Re: cs proposal straw vote
In-Reply-To: Msg of Wed, 22 Feb 89 12:08:15 PST from Thom Linden <baggins@IBM.com>

>   I would like to take a straw vote on various components of
> the Characters proposal.  The primary intent is to resolve the
> actual list of items to be voted upon at the March meeting.
> Let me know if you think some items should be separated or
> combined
...
> Issue: CHAR-FONT-UNUSED-CHAR-BITS-NONPORTABLE
> Problem: CHAR-FONT isn't used, CHAR-BITS isn't portable.
> Proposal:
>           Eliminate of font and bit attributes.
>           Add rules for an implementation supporting attributes.
>           Redefine STRING-CHAR as implementation defined.
>           Remove CHAR-FONT-LIMIT
>           Remove CHAR-BITS-LIMIT
>           Remove INT-CHAR
>           Remove CHAR-BITS
>           Remove CHAR-FONT
>           Remove MAKE-CHAR
>           Remove CHAR-CONTROL-BIT
>           Remove CHAR-META-BIT
>           Remove CHAR-SUPER-BIT
>           Remove CHAR-HYPER-BIT
>           Remove CHAR-BIT
>           Remove SET-CHAR-BIT

Yes, I can accept this.
---

> Issue: CHAR-INT-ONLY-USEFUL-WHEN-ATTRIBUTES-SUPPORTED
> Problem: CHAR-INT behavior is CHAR-CODE unless implementation
>   defined attributes are supported.
> Proposal:
>           Remove CHAR-INT

I had to stop and think about why this wasn't part of the previous issue.
Perhaps the thought was that a portable way to turn all of a character into
a number (e.g. for a hash code) would be desirable even if only some
implementations support attributes?  That sounds like a legitimate
concern, so I vote No.
                   --

> Issue: CHARACTER-TYPE-RESTRICTIVEC
> Problem: CHARACTER type doesn't allow thin & fat characters.
> Proposal:                                                                a
>           Define BASE-CHARACTER as a subtype of STRING.                  a
>           Standard characters are a subset of the base
>              characters.
>           STANDARD-CHAR type is replaced by (CHARACTER :STANDARD)
>           Remove the semi-standard characters.

I have been unable to imagine the reason for linking semi-standard
characters with fat characters; these should be separate issues.

Yes to fat characters.
---
No to removing the semi-standard characters.  I still have yet to hear a
--    plausible rationale for doing this.

> Issue: STRING-TYPE-RESTRICTIVE
> Problem: STRING type doesn't allow thin & fat strings.
> Proposal:                                                                a
>           Define STRING as a union type                                  a
>           STRING used as a type specifier for object creation
>              means (VECTOR CHARACTER)
>           All string functions operate as specified on any               a
>              string object except it is an error to insert
>              an extended character into a base string.
>           Extend the COERCE function to allow coercion from              a
>             base string to extended string.

Yes.
---

> Issue: STRING-TYPE-ABBREVIATIONS
> Problem: new types are awkward to name, want abbreviations.
> Proposal:                                                                ne
>           Add BASE-STRING
>           Add GENERAL-STRING

Yes.
---

> Issue: SIMPLE-STRING-TYPE-RESTRICTIVE
> Problem: SIMPLE STRING type doesn't allow thin & fat strings.
> Proposal:                                                                a
>           Define SIMPLE-STRING as a union type                           a
>           Define SIMPLE-STRING as a type specifier for object
>              creation means (SIMPLE-ARRAY CHARACTER (size))

Yes.
---
> Issue: SIMPLE-STRING-TYPE-ABBREVIATIONS
> Problem: new types are awkward to name, want abbreviations.
> Proposal:                                                                ne
>           Add SIMPLE-BASE-STRING
>           Add SIMPLE-GENERAL-STRING

Yes.
---
> Issue: FILE-EXTERNAL-REPRESENTATION
> Problem: can't specify external encoding even when there are lots
> Proposal:
>           Add :EXTERNAL-CODED-CHARACTER-FORMAT keyword to OPEN

Yes.
---
> Issue: STRING-BINARY-WIDTH
> Problem: Can't find out how many bytes a string will take when written as
> text
> Proposal:
>           Add :EXTERNAL-CODED-STRING-LENGTH function

No; I'm not sure that this has been adequately thought out.
--
> Issue: CHAR-CODE-NON-PORTABLE
> Problem: no way to talk about well-known external coding methods, only
> internal codes
> Proposal:
>           Add CHAR-CCS-VALUE function

Yes, although I'm not too happy about the name; "value" doesn't really say
---  much.  Why not CHAR-CCS-INDEX ?  Or CHAR-EXTERNAL-CODE ?  Yes also to
     the inverse function.

> Issue: CHARACTER-IDENTIFICATION-NONPORTABLE
> Problem: Can't portably talk about non-standard characters
> Proposal:
>            Introduce the concept of Registries
>            Standardize on #\registry:id, add all-implemented-registries
>            Add *ALL-CHARACTER-REGISTRY-NAMES* variable
>            Add FIND-CHAR function
>            Add CHAR-LABEL function
>            Add CHAR-REGISTRY-NAME function
>            New syntax for CHARACTER type specifier
>            New #\label:registry character name syntax
>            New argument to CHARACTERP

No.  I'm not convinced that this approach is feasible or even necessary.
---  There appears to be a great deal of machinery being created solely to
     support the premise stated in section 2.2 that all characters need to
     be decomposable into one and only one name.  I don't see the need for
     that.

∂02-Mar-89  0929	X3J13-mailer 	cs proposal comments 
Received: from IBM.COM by SAIL.Stanford.EDU with TCP; 2 Mar 89  09:29:33 PST
Date: Thu, 02 Mar 89 02:20:21 PST
From: Thom Linden <baggins@IBM.com>
To: Common Lisp mailing <x3j13@sail.stanford.edu>
Message-ID: <890302.022021.baggins@almvma>
Subject: cs proposal comments


>>   But if we decide that "my alpha" _is_ the same as "your alpha", then which
>>   of our languages' registry gets to include it?  I can see a lot of
>>   confusion over characters that are used the same in more than one
>>   language.

I don't see the confusion.  German, English, Italian, etc. have a large
overlap of characters.  One would expect these to all be in a single
registry, eg. Latin.  Again, the important factor is that a character
is uniquely named.  There is no advantage of one registry over another.

>>
>>   I'm not so much concerned with who decides this as with whether this
>>   approach is even feasible.  The lack of even a "for example" scenario of
>>   how this might work leaves me with a lot of doubts about whether it _can_
>>   work.  Also, it is not apparent why anyone outside the Common Lisp
>>   community would have any interest in participating in such a standards
>>   effort.

I believe other languages have the same problems as Lisp.  For example,
COBOL has standardized names for coded character sets in
their I/O interface.  In particular, SC22 wants to address the
international character handling issues across all (prog.)languages.
I'm attending an SC22 ad hoc committee meeting on characters next
week (and will let this forum know what interest I find).

>>
>>
>>   Page 7 of the draft dated February 21 says that
>>
>>     "The proposed ISO Character Registry Standard is fixed; an
>>      implementation may not extend a standard registry's constituent
>>      set of characters beyond the standard definition."
>>
>>   That says to me that if an implementation is going to add a character,
>>   then it can only be added to an implementation-defined registry.  What
>>   happens then if a new edition of the registry standard includes that
>>   character in one of the standard registries?  Since a character is not
>>   permitted to be a member of more than one registry, that immediately
>>   becomes an incompatible change for anyone who has been using that
>>   character.  Consequently, even extensions by standards revision will be
>>   discouraged.  That seems quite non-extensible to me.

Nothing prevents the implementation from providing a warning message
and behaving properly for some period of time.  Users are encouraged
to use a 'new' standardized name since that name has a portable
meaning.
But, what the statement says to me is that if I use a name in the
standard registry, I have a guarentee that it does not have an
implementation unique meaning.  Also, it is impossible for an
implementation to add character names which conflict with any
'new' standardized character.

>>
>>
>>   So CHAR< etc. have no portable meaning unless both arguments are standard
>>   characters in one of the partial ordering groups on page 237 of CLtL?
>>   If you are going to have a Greek alphabet that is required to be disjoint
>>   from the Latin alphabet anyway, wouldn't you want to know that the Greek
>>   letters could be sorted in the expected order?

Well, I don't know the 'expected' order for Greek.  In general, the
expected order is culturally dependent and using CHAR< as a sorting
mechanism is not sufficient.  If we take the Latin registry
as including accented characters,  there are different orderings
depending on whether you are in a Spanish, German, Danish, etc.
context.  For Common Lisp to impose a single one is certainly
be wrong.  In general, I don't think the ordering of individual
characters by CHAR< is as important as standardized definitions
of ordering strings for culturally expected results (such as, dictionary
ordering).

>>
>>   > >>   Page 25 section A.4.5 doesn't specify the syntax of a registry name; did
>>   > >>   you intend it to be a string?
>>   >
>>   > These have been changed to be symbols.
>>
>>   Fine, but it appears that the new draft still doesn't say that.
>>
>>   > >>   Page 29 - *ALL-REGISTER-NAMES* -- a list of strings?
>>   >
>>   > Now a list of symbols.
>>
>>   Again, the document doesn't say that.

p24,26,28,33:  Right.  I actually said they are 'names'.  This may be
too general and can be changed to 'keyword symbols' without any
difficulty.

>>
>>   That sounds good, but don't we also need the inverse function, to
>>   construct a character object given a CCS and index?
>>
>>   >
>>   > That really depends on the definition of a conforming program. Is
>>   > this defined yet?
>>
>>   Never mind that; the real question is why do you want the standard to not
>>   specify the meaning of tabs and form-feeds in source files?
>>
I don't have my CLtL with me but I don't think a meaning is given
to the semi-standard characters (unless we consider them self defining?)

>>
>>   In the character table on page 17, do the "graphic labels" have any
>>   significance?  I don't see that the document uses them or requires them to
>>   be used in any way.  If not, that column should be deleted.  I hope that
>>   this is _not_ an example of what character names in a registry would look
>>   like.

It is simply an assist in uniquely identifing each standard character
since glyphs can be ambigious.


>>
>>   Your message of January 24 said you were going to:
>>
>>     -- modify char-name, name-char, and #\name  to accept character
>>          names of the form 'registry:label'
>>
>>   but I can't see that this draft does that.  In particular, it is not at
>>   all apparent how this is supposed to affect CHAR-NAME.  Should I expect
>>   (CHAR-NAME #\NEWLINE) to return "NEWLINE" or something like
>>   "CONTROL:NEWLINE"?  Are #\SPACE and #\NEWLINE to be the only characters
>>   that can be referenced by a name that does not included a registry prefix?
>>   Since all characters will have a label in some registry, does that mean
>>   that CHAR-NAME will never return NIL anymore?

The form label:registry is given on p38 where for #\, "In particular,
an implementation may support names of the form label:registry."
It could do with repeating on p35 (name-char, char-name).

If a 'control' registry is standardized, I would expect these names
to replace (eventually) the various names now used.  Some revision
of the Common Lisp standard might deprecate the current forms once
(if) a Character Registry standard is adopted.



∂02-Mar-89  1000	X3J13-mailer 	Re: cs proposal and straw vote 
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 2 Mar 89  09:59:49 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA03605; Thu, 2 Mar 89 10:57:45 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA03241; Thu, 2 Mar 89 10:57:42 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903021757.AA03241@defun.utah.edu>
Date: Thu, 2 Mar 89 10:57:40 MST
Subject: Re: cs proposal and straw vote
To: baggins@ibm.com
Cc: x3j13@sail.stanford.edu
In-Reply-To: Dan L. Pierson <pierson@mist.encore.com>, Wed, 01 Mar 89 15:49:59 EST

I pretty much agree with the points Dan raised.  I generally support
(with varying degrees of enthusiasm) all of the subissues except the
last one, dealing with character registries. 

My major complaints at this point are:

  - I also don't feel that I could vote for the document in its current
    form.  At the very least, there should be some kind of cross-reference
    indicating which parts of the document correspond to which of the
    subissues you've identified, so that we know exactly what language
    we are voting on for each of them.  And, I would still like to see 
    a rationale presented for each of the subissues.

  - I really believe it would be premature to standardize on the idea of
    character registries at this time.  I don't think that the idea is
    inherently bad and awful, but given that the specifics of the proposal
    do not appear to have stabilized and nobody has implemented it yet, I
    think we would be running an unacceptable risk of standardizing the
    wrong thing.  


A few other nits:

I'm confused about what happens to the STRING-CHAR type.  There is a
definition for it on page 22 but on the bottom of page 23 it is
removed from the table of standard type specifiers.  And, which
subissue would removing it fall under?  It's not mentioned in any of
the ones you list.

On page 28, it says: "There may be unassigned codes between 0 and
char-code-limit which are not legal arguments to code-char."  Don't
you really mean to say "... for which code-char returns NIL"?

Why do we need CHAR-CODE-LIMIT, CODE-CHAR, and CHAR-CODE anyway?
While bits and fonts were in the standard, these were useful for
things like creating a character with the same code but different bits
or font attributes, but now that's out.  If we want a function to use
for hashing characters, that's what CHAR-INT is for.  The only other
use I can think of is supporting iteration over characters, and it
seems like this could be extremely inefficient in implementations that
support user-defined character sets.  (In such a case, I would imagine
that one would make CHAR-CODE-LIMIT correspond to the limit imposed by
the representation, perhaps the same as MOST-POSITIVE-FIXNUM, but in
actual practice, very few of those codes would have corresponding
characters.)  I agree with Dan that we'd be better off having a
specialized iterator.

Should we consider extending MAKE-STRING-OUTPUT-STREAM to take an
:ELEMENT-TYPE keyword?

-Sandra
-------

∂02-Mar-89  0905	X3J13-mailer 	Section 2.2 - part 5 
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 2 Mar 89  09:05:12 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA05377; Thu, 2 Mar 89 09:03:02 PST
Message-Id: <8903021703.AA05377@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
	for x3j13@sail.stanford.edu; id AA05377; Thu, 2 Mar 89 09:03:02 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 2 Mar 89 07:42
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: Section 2.2 - part 5


%% 2.8.0 1
\beginsubsubsection{\datatype Package} 
 
An {\word object} of type {\datatype package} (a {\datatype package}) 
is a namespace that holds collections
of {\datatype symbols\/}.
%% 10.0.0 7
%% 11.0.0 4
 
A {\datatype package} is a data structure
that establishes a mapping from print
names to {\datatype symbols}. 
At any given time one
{\datatype package} 
is current. The current {\datatype package} is
the one that is the
value of @var[package]\rm.  It is possible to refer to
{\datatype symbols} in
{\datatype packages} 
other than the current one through the use of
package qualifiers in the representation of the {\datatype symbol}.
 
%% 11.0.0 5
The mappings in a {\datatype package} are divided
into two classes, external and internal.  The
{\datatype symbols} accessible via these different mappings are 
called external and
internal {\datatype symbols} 
of the {\datatype package}. Within a
{\datatype package}, 
a print name refers to one {\datatype symbol} or to none; if it does refer
to a {\datatype symbol}, then it is either external or internal in that
{\datatype package}, but not both.
%% 11.0.0 6
External {\datatype symbols} are part of the package's public interface to other
{\datatype packages}. 
{\datatype Symbols} become external 
if they appear in {\function export}.
 
%% 11.0.0 7
A {\datatype symbol} 
will always have the same
print name no matter what {\datatype package} 
it appears in, but it may be external in some {\datatype
packages}
and internal in others. 
A {\datatype symbol} 
will not necessarily always have the same
printed representation because of the presence of package qualifiers ({\tt
:} and {\tt ::}).
 
%% 11.0.0 9
{\datatype Packages} 
may be built up in layers.  From the point of view of a
{\datatype package's} user, 
the {\datatype package} is a single collection of mappings from
{\datatype strings} into internal and external {\datatype symbols}.  
However, some of these
mappings may be established within the package itself, while other
mappings are inherited from other packages via {\function use-package}.
A {\datatype symbol} is
accessible in a {\datatype package} if it can be referred to
without a package qualifier when that {\datatype package} is current,
regardless of whether the mapping occurs within
that {\datatype package} 
or via inheritance.   A {\datatype symbol} is
present in a {\datatype package} 
if the mapping is in the {\datatype package} itself and is
not inherited from somewhere else.
 
%% 5.1.2 6
%% 11.3.0 5
The {\datatype package} 
named @f[keyword] contains all keyword {\datatype symbols} 
used by the
@clisp\ system and by user-written code.  Such {\datatype symbols} must be
easily accessible from any {\datatype package};
name conflicts are not an issue
because these {\datatype symbols\/}
are used only as labels, not to carry package-specific 
attributes.
When a  {\datatype symbol} is added to the @f[keyword] package, it
is made external, declared to be a constant, and is
made to
have itself as its value.  
 
 
%% 11.0.0 19
Each {\datatype package} has a name (a {\datatype string}) 
and perhaps some nicknames.  These
are assigned when the {\datatype package} is created
and can be changed
later.  
 
%% 11.0.0 20
There is a single namespace for {\datatype packages}.  
The function @Funref[find-package] translates a package
name or nickname into the
associated {\datatype package}.  
The function @Funref[package-name] returns the name of a
{\datatype package}.  
The function @Funref[package-nicknames] returns a {\datatype list} of all
nicknames for a {\datatype package}.  
@Funref[rename-package] removes a
{\datatype package's} 
current name and nicknames and replaces them with new ones
specified by the caller.
 
%% 11.0.0 35
{\datatype Symbols} from one {\datatype package} 
may be made accessible in another {\datatype package} in
two ways.
 
%% 11.0.0 36
\beginlist 
\itemitem{--}
Any individual {\datatype symbol} 
may be added to a {\datatype package} by use
of @Funref[import]\rm.  After the call to
{\function import} 
it is possible to refer to the {\datatype symbols}
in the importing package
without any qualifier.  The status of the {\datatype symbol}
in the {\datatype package} 
it came from
is unchanged, and home package
for
this {\datatype symbol } is unchanged.
Once imported, a {\datatype symbol} is present in the
importing package
and can be removed only by calling {\function unintern}.
 
%% 11.4.0 4
A {\datatype symbol} is shadowed by another {\datatype symbol} in
some {\datatype package} 
if the first {\datatype symbol} would be accessible by inheritance
if not for the presence of the second {\datatype symbol}.
The function @Funref[shadowing-import] causes the first {\datatype symbol} 
to be imported without error
even if the second {\datatype symbol} is accessible.
 
%% 11.4.0 39
%% 11.4.0 40
\itemitem{--}
The second mechanism for making symbols from one package accessible in another
is provided by @Funref[use-package]\rm.  
The function {\function unuse-package} 
undoes the effects of a previous {\function use-package}.  
\endlist
 
 
%% 11.4.0 
There is no way to inherit the internal {\datatype symbols} 
of another {\datatype package};
to refer to an internal {\datatype symbol}, 
the {\datatype symbol's} home
package must be made current, 
a qualifier must be used, or the {\datatype symbol} 
must be imported into the current
{\datatype package}.
 
%% 11.4.0 8
When a {\datatype symbol} is to be located in a
given {\datatype package} 
the following occurs:
\beginlist 
\itemitem{--} The {\datatype symbol} is looked for among the external and
internal {\datatype symbols} of the 
{\datatype package} itself.
\itemitem{--} The
external {\datatype symbols} of the used {\datatype packages} are looked through
in some unspecified order.  The
order does not matter; see the rules for handling name
conflicts listed below. 
\endlist
 
%% 11.0.0 46
Within one {\datatype package}
any particular print name can refer to at most 
one {\datatype symbol}.  A name conflict
is said to occur when there is more than one candidate {\datatype symbol}.
Any time
a name conflict is about to occur,
a continuable error is signalled.  
 
 
The following rules apply to name conflicts:
%% 11.0.0 47
\beginlist
%% 11.0.0 49
\itemitem{--}
Name conflicts are detected when they become possible, that is, when the
package structure is altered.  Name
conflicts are not checked for during every name lookup.
 
\itemitem{--}
If the same {\datatype symbol} 
is accessible to a {\datatype package} through more than
one path, there is no name conflict.
The same identical {\datatype symbol} cannot conflict with itself.
Name conflicts occur only between distinct {\datatype symbols} with
the same print name.
 
%% 11.0.0 48
\itemitem{--} Every {\datatype package} has a
list of shadowing {\datatype symbols}.  
A shadowing {\datatype symbol} takes precedence over any
other {\datatype symbol} of the same print name 
that would otherwise be accessible in the
{\datatype package}.  
A name conflict involving a shadowing symbol is always
resolved in favor of the shadowing {\datatype symbol}, 
without signalling an error
(except for one exception involving {\function import}).
See @Funref[shadow] and @Funref[shadowing-import]\rm.
 
 
%% 11.0.0 50
\itemitem{--} 
The functions {\function use-package}, {\function import}, and {\function export} 
check for name
conflicts.  
 
%% 11.0.0 52
\itemitem{--} 
{\function shadow} and {\function shadowing-import} 
never signal a name-conflict error.
 
%% 11.0.0 53
\itemitem{--} 
{\function unuse-package}, {\function unexport}, and {\function unintern} 
(when the {\datatype symbol} 
being
uninterned is not a shadowing symbol) do not need to do any
name-conflict checking.
 
%% 11.0.0 54
\itemitem{--} 
Giving a shadowing symbol to {\function unintern} 
can uncover a name conflict that had
previously been resolved by the shadowing.  
 
%% 11.0.0 55
\itemitem{--} 
Aborting from a name-conflict error leaves the original {\datatype symbol} 
accessible.
 
\itemitem{--} 
Package functions signal name-conflict errors before making any
change to the package structure.  When multiple changes are to be made,
it is
permissible for the implementation to process each change separately,
so that aborting from a name
conflict caused by the second {\datatype symbol} 
in the {\datatype list} will not unexport the
first {\datatype symbol} in the {\datatype list}.  
Multiple changes could be made with {\function export}.
 
%% 11.0.0 56
\itemitem{--} 
Continuing from a name-conflict error should offer the user a chance to
resolve the name conflict in favor of either of the candidates.  The
{\datatype package} 
structure should be altered to reflect the resolution of the
name conflict, via {\function shadowing-import}, 
{\function unintern}, or {\function unexport}.
 
%% 11.0.0 57
\itemitem{--} 
A name conflict in {\function use-package} 
between a {\datatype symbol} directly present in the
using {\datatype package} 
and an external {\datatype symbol} of the used 
{\datatype package} is resolved
in favor of the first {\datatype symbol} 
by making it a shadowing {\datatype symbol}, or in favor
of the second {\datatype symbol} 
by uninterning the first {\datatype symbol} from the using
{\datatype package}. 
 
%% 11.0.0 60
\itemitem{--} 
A name conflict in {\function export} or {\function unintern} 
due to a {\datatype package's}
inheriting two distinct {\datatype symbols} 
with the same print name from two other
{\datatype packages} 
may be resolved in favor of either {\datatype symbol} by importing it into
the using {\datatype package} 
and making it a shadowing symbol, just as with
{\function use-package}.
\endlist
 
%% 11.2.0 5
Figure {\chapno--\the\capno} 
lists the {\word tools} that are applicable
to {\datatype packages}. 
For the {\word operators} listed here, all optional arguments named
{\arg package} default to the current value of @var[package]\rm.  Where an
{\word operator} 
takes an argument that is either a {\datatype symbol} or a {\datatype list} 
of {\datatype symbols},
an argument of @false\ is treated as an empty {\datatype list} of 
{\datatype symbols}.  Any {\arg package} 
argument may be either a {\datatype string}, a {\datatype symbol}, or
a {\datatype package}.
If a {\datatype symbol} 
is supplied, its print name will be used as the {\datatype package}
name.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
@var[package] & {\tt make-package} & {\tt in-package} \cr
{\tt find-package }&{\tt  package-name }&{\tt  package-nicknames }\cr
{\tt rename-package }&{\tt  package-use-list }&{\tt  package-used-by-list }\cr
{\tt package-shadowing-symbols }&{\tt  list-all-packages }&{\tt  intern }\cr
{\tt find-symbol }&{\tt  unintern }&{\tt  export }\cr
{\tt unexport }&{\tt  import }&{\tt  shadowing-import }\cr
{\tt shadow }&{\tt  use-package }&{\tt  unuse-package }\cr
{\tt find-all-symbols }&{\tt  do-symbols }&{\tt  do-external-symbols }\cr
{\tt do-all-symbols }&{\tt  modules }&{\tt  provide }\cr
{\tt require }& & \cr
 
\noalign{\vskip -9pt}
}}
\caption{Package tools}
\endfig
 
%% 11.6.0 1
The following packages, at least, are built into every @clisp\ system:
 
%% 11.6.0 2
\beginlist
\itemitem{\tt lisp}
 
%% clean-up issue `contains all and only'
The package named @f[lisp] contains the primitives of the
@clisp\ system.  Its external symbols include all of the
user-visible functions and global variables that are present in the
@clisp\ system, such as {\function car}, {\function cdr}, @var[package]\rm, etc.
 
%% 11.6.0 3
\itemitem{\tt user}
 
%% clean-up issue `lisp package and may use other packages as well'
The @f[user] package is the value of @var[package] when 
a @clisp\ system starts up.  This package uses the @f[lisp] package.
 
%% 11.6.0 4
\itemitem{\tt keyword}
 
This package contains all of the keywords used by built-in
or user-defined @xlisp\ functions.  Printed symbol representations
that start with a colon are interpreted as referring to symbols
in this package, which are always external symbols.  All symbols in this
package are treated as constants that evaluate to themselves.
The function {\function symbol-value} may be used to retrieve these values.
 
%% 11.6.0 5
\itemitem{\tt system}
 
This package name is reserved to the implementation,
uses the @f[lisp] package, and has the
nickname @f[sys]\rm. 
\endlist
 
 
\beginsubsubsection{\datatype Pathname} 
 
%% 23.1.1 1
All file systems dealt with by @clisp\ are forced into a common framework
in which files are named by an object of type {\datatype pathname},
a {\datatype pathname},
that can be translated by the underlying operating system to a file
name.
 
 
%% 23.1.1 3
A {\datatype pathname} always has six components, described below.  
These components
are the common interface that allows programs to work the same way with
different file systems; the mapping of the pathname components into the
concepts peculiar to each file system is 
implementation-dependent.
 
%% 23.1.1 4
\beginlist
 
 
%% 23.1.1 5
%% 23.1.1 17
 
\itemitem{\bf Host}
 
The name of the file system on which the file resides.
The host may be a
{\datatype string}, indicating a file system, or a 
{\datatype list}
of {\datatype strings}, 
of which the first names the file system and the rest
may be used for inter-network routing.
 
 
\itemitem{\bf Device}
 
Corresponds to the ``device'' or ``file structure'' concept in many
host file systems: the name of a (logical or physical) device containing files.
 
 
%% 23.1.1 6
\itemitem{\bf Directory}
 
Corresponds to the ``directory'' concept in many host file systems:
the name of a group of related files.
 
%% 23.1.1 7
\itemitem{\bf Name}
 
The name of a group of files that can be thought of as
conceptually the ``same'' file.
 
%% 23.1.1 8
%% 23.1.1 15
\itemitem{\bf Type}
 
Corresponds to the ``filetype'' or ``extension'' concept in many host
file systems.  This says what kind of file this is.  
The type is always a {\datatype string}, @nil\ or {\keyword :wild}.
When the type is not supplied, its value is implementation-dependent.
 
%% 23.1.1 9
%% 23.1.1 16  
\itemitem{\bf Version}
 
Corresponds to the ``version number'' concept in many host file systems.
 
The version is either a positive {\datatype integer} 
or a {\datatype symbol } from the following list:
{\function nil}, {\keyword :wild}, or 
{\keyword :newest} (refers to the largest version number
that already exists in the file system when reading a file, or to
a version number
greater than any already existing in the file system
when writing a new file).  Implementations 
may define other special version {\datatype symbols}.
\endlist
 
The following rules apply to the components of a {\datatype pathname}.
 
%% 23.1.1 12
\beginlist
\itemitem{--}
Not all of the components of a {\datatype pathname} 
need to be supplied.  If a
component of a {\datatype pathname} 
is missing, its value is @nil\rm.  Before the file
system interface can do anything with a file, such as opening the
file, all the missing components of a {\datatype pathname} must be filled in
from a set of defaults.  
Parsing a namestring
that does not contain certain components will result in a 
{\datatype pathname} with
missing components.
 
%% 23.1.1 13
\itemitem{--}
A component of a {\datatype pathname} can also be the keyword {\keyword
:wild},
which means that the {\datatype pathname}
component matches anything.
 
%% 23.1.1 14
\itemitem{--}
Except where otherwise specified, the values 
for components of a {\datatype pathname} are
implementation-dependent.  
 
%% 23.1.1 18
\itemitem{--}
The device, directory, and name components can each be a {\datatype string} 
(with
implementation-dependent rules on allowed characters and length) or possibly
some other @clisp\ {\word object}
which has an implementation-dependent format.
Supplying a {\datatype string} 
as a pathname component for a host that requires an {\word object} as a
component will cause conversion of the {\datatype string} to the appropriate
{\word object}.
 
\endlist
 
%% 23.1.1 10
A {\datatype pathname} 
is not necessarily the name of a specific file.
Rather, it is a specification (possibly only a partial specification) of
how to access a file.  
A {\datatype pathname} 
need not correspond to any file that
actually exists, and more than one {\datatype pathname} 
can refer to the same file.
For example, the {\datatype pathname} 
with a version of {\keyword :newest} may refer to the
same file as a {\datatype pathname} 
with the same components except a certain number
as the version.  Indeed, a {\datatype pathname} 
with version {\keyword :newest} may refer to
different files as time passes, because the meaning of such a {\datatype
pathname}
depends on the state of the file system.  
 
%% 23.1.1 11
{\datatype Pathnames} that are specified by {\datatype strings} 
(called namestrings) are parsed and
merged.  Parsing is the conversion of a namestring
into a {\datatype pathname}. This operation is
implementation-dependent, because the format of namestrings
is implementation-dependent.
Merging takes a {\datatype pathname} with missing components
and supplies values for those components from a source of defaults.
 
%% 23.1.1 20
An implementation is free to accommodate other file system features in its
{\datatype pathname} representation and provide a parser that can process such
specifications in namestrings. A program that
depends explicitly on any such features will not be portable.
The following figures contain lists of {\word tools} that are applicable to the
file system interface.
 
 
Figure {\chapno--\the\capno} lists the {\datatype pathname} {\word tools}.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr                                                           
\noalign{\vskip -9pt}                               
{\tt pathname }&{\tt  truename }&{\tt  parse-namestring }\cr
{\tt merge-pathnames }& @var[default-pathname-defaults]&{\tt  make-pathname }\cr
{\tt pathnamep }&{\tt  pathname-host }&{\tt  pathname-device }\cr
{\tt pathname-directory }&{\tt  pathname-name }&{\tt  pathname-type }\cr
{\tt pathname-version }&{\tt  namestring }&{\tt  file-namestring }\cr
{\tt directory-namestring }&{\tt  host-namestring }&{\tt  enough-namestring }\cr
{\tt user-homedir-pathname } & & \cr
\noalign{\vskip -9pt} }}
\caption{File System Interface tools - 1}  
\endfig
 
 
Figure {\chapno--\the\capno} lists the file and directory {\word tools}.
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt directory} &{\tt  open }&{\tt  with-open-file }\cr
{\tt rename-file }&{\tt  delete-file }&{\tt  probe-file }\cr
{\tt file-write-date }&{\tt  file-author }&{\tt  file-position }\cr
{\tt file-length} & {\tt load} & @var[load-verbose] \cr
\noalign{\vskip -9pt} }}
\caption{File System Interface tools - 2}  
\endfig
 
%% 2.11.0 1
\beginsubsubsection{\datatype Random-state}
 
An {\word object} of type {\datatype random-state} (a {\datatype random-state}
object) 
contains state information used by the pseudo-random number generator.
%% 12.9.0 1
The pseudo-random numbers 
in a random number series are implementation-dependent,
but the distribution of the numbers should
be machine-independent.
Figure {\chapno--\the\capno} lists
the {\word tools} that are applicable to {\datatype random-state}.
 
 
 
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt random} & @var[random-state] & \cr
{\tt make-random-state} & {\tt random-state-p} & \cr
\noalign{\vskip -9pt}
}}
\caption{Random-state tools}
\endfig
 
\issue{FUNCTION-TYPE:X3J13-MARCH-88}
\beginsubsubsection{\datatype Function}
 
An {\word object} of type {\datatype function\/} is called a {\datatype
function}.
A {\datatype function}
may be supplied as an argument without error to @Funref[funcall]
or @Funref[apply]\rm, and is
to be executed as code when arguments are supplied.
The functional computation produces one or more values, produces no 
values, or
takes a non-local exit.
The type {\datatype function} has at least one {\word subtype} called
{\datatype compiled-function}.
Implementations are free to define other {\word subtypes} of 
the type {\datatype function}.
 
\beginsubsubsection{\datatype Compiled-function}
 
An object of type {\datatype compiled-function} is a called a {\datatype
compiled-function}.
%% 2.13.0 2
A {\datatype compiled-function} is a compiled code {\word object}
that has been produced by the 
compiler.
\endissue{FUNCTION-TYPE:X3J13-MARCH-88}
 
\beginsubsubsection{\datatype Nil} 
 
The empty data type, which contains no {\word objects}, is
denoted by @nil\rm.  
 
\beginsubsubsection{\datatype Common}
 
The type {\datatype common} encompasses all the
{\word objects} required by the @clisp\ language.  An implementation
is free to provide other 
{\word types} that are not {\word subtypes} of the type {\datatype common}.
 
 
\endsubSection%{Data Type Definition}
 
%% Type Specifiers
\beginsubSection{Type Specifiers}
 
 
\issue{ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS:UNIFY-UPGRADING}
The following will be deleted:
 
%% 4.5.0 5        
Type specifiers are used for two different purposes:
declaration and discrimination.  
\endissue{ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS:UNIFY-UPGRADING}
There are two reasons that an {\word object}'s type is used:
\beginlist
\itemitem{1.} The consequences are undefined if an 
{\word object} is an argument to an {\word operator}
and the argument 
is not one of the {\word operator}'s required {\word types}.
\itemitem{2.} If run-time optimizations in compiled code are desired,
it is often necessary to reduce the number of {\word types} of {\word objects}
a variable can hold.
\endlist
%% 4.1.0 1
The type specifiers (they are {\datatype symbols})
defined by the system are those shown in Figure 
{\chapno--\the\capno}.
 
%% 4.3.0 4
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt array}&{\tt integer}&{\tt short-float}\cr
{\tt atom}&{\tt keyword}&{\tt signed-byte}\cr
{\tt bignum}&{\tt list}&{\tt simple-array}\cr
{\tt bit}&{\tt long-float}&{\tt simple-bit-vector}\cr
{\tt bit-vector}&{\tt mod}&{\tt simple-string}\cr
{\tt character}&{\tt nil}&{\tt simple-vector}\cr
{\tt common}&{\tt null}&{\tt single-float}\cr
{\tt compiled-function}&{\tt number}&{\tt standard-char}\cr
{\tt complex}&{\tt package}&{\tt stream}\cr
{\tt cons}&{\tt pathname}&{\tt string}\cr
{\tt double-float}&{\tt random-state}&{\tt string-char}\cr
{\tt fixnum}&{\tt ratio}&{\tt symbol}\cr
{\tt float}&{\tt rational}&{\tt t}\cr
{\tt function}&{\tt readtable}&{\tt unsigned-byte}\cr
{\tt hash-table}&{\tt sequence}&{\tt vector}\cr
\noalign{\vskip -9pt} }}
\caption{Table of Atomic Type Specifiers}
\endfig
 
                      
The syntax for type specifiers is illustrated in Figure {\chapno--\the\capno}.
\boxfig
{\advance\baselineskip by 2.5pt
\halign{\hskip\leftskip\hfil#&#\hfil\cr
{\it typespec\/}::$=\;$&{\it atomic-type-specifier\/}\cr
$\vert\;$& \paren {{\tt satisfies} predicate-name\/}\cr
$\vert\;$& \paren {{\tt member} \star{\curly{object}}}\cr
$\vert\;$& \paren {{\tt not} typespec\/}\cr
$\vert\;$& \paren {{\tt and} \star{\curly{typespec}}}\cr
$\vert\;$& \paren {{\tt or} \star{\curly{typespec}}}\cr
$\vert\;$& \paren {{\tt array} {\ttbrac{\curly{typespec $\vert$ {\tt *} } \brac{dimensions}}}}\cr
$\vert\;$& \paren {{\tt simple-array} {\ttbrac{\curly{typespec $\vert$ {\tt *} } \brac{dimensions}}}}\cr
$\vert\;$& \paren {{\tt vector} {\ttbrac{\curly{typespec $\vert$ {\tt *} } \brac{\curly{size $\vert$ {\tt *}}}}}}\cr
$\vert\;$& \paren {{\tt simple-vector} \ttbrac{\it size\/}}\cr
$\vert\;$& \paren {{\tt string} \ttbrac{\it size\/ $\vert$ {\tt *}}}\cr
$\vert\;$& \paren {{\tt simple-string} \ttbrac{\it size\/ $\vert$ {\tt *}}}\cr
$\vert\;$& \paren {{\tt bit-vector} \ttbrac{\it size\/ $\vert$ {\tt *}}}\cr
$\vert\;$& \paren {{\tt simple-bit-vector} \ttbrac{\it size\/ $\vert$ {\tt *}}}\cr
$\vert\;$& \paren {{\tt integer} \ttbrac{integer-limit \brac{integer-limit}}}\cr
$\vert\;$& \paren {{\tt fixnum} \ttbrac{fixnum-limit \brac{fixnum-limit}}}\cr
$\vert\;$& \paren {{\tt mod} \ttbrac{\it integer\/ $\vert$ {\tt *}}}\cr
$\vert\;$& \paren {{\tt signed-byte} \ttbrac{\it size\/ $\vert$ {\tt *}}}\cr
$\vert\;$& \paren {{\tt unsigned-byte} \ttbrac{\it size\/ $\vert$ {\tt *}}}\cr
$\vert\;$& \paren {{\tt rational} \ttbrac{rational-limit \brac{rational-limit}}}\cr
$\vert\;$& \paren {{\tt float} \ttbrac{float-limit \brac{float-limit}}}\cr
$\vert\;$& \paren {{\tt short-float} \ttbrac{short-float-limit \brac{short-float-limit}}}\cr
$\vert\;$& \paren {{\tt single-float} \ttbrac{single-float-limit \brac{single-float-limit}}}\cr
$\vert\;$& \paren {{\tt double-float} \ttbrac{double-float-limit \brac{double-float-limit}}}\cr
$\vert\;$& \paren {{\tt long-float} \ttbrac{long-float-limit \brac{long-float-limit}}}\cr
$\vert\;$& \paren {{\tt complex} \ttbrac{typespec $\vert$ {\tt *}}}\cr
$\vert\;$& \paren {{\tt function} \ttbrac{arg-typespec-list \brac{value-typespec}}}\cr
}}
\caption{Syntax for Type Specifiers}                                 
\endfig
                                                                     
Figure {\chapno--\the\capno} gives the definitions 
applicable to the syntax for type specifiers.
 
 
\boxfig
{\advance\baselineskip by 2.5pt
\halign{#\hfil&#\hfil\cr
{\it arg-typespec-list\/}::$=$ \vtop{\hbox{\star{(\curly{typespec}}
\ttbrac{{\opt}  {\star{\curly{typespec\/}}}}
\ttbrac{{\rest}  {\it typespec\/}}
\hbox{\quad\ttbrac{{\key{}} \star{\curly{\it typespec\/}}}{\rm )}}}} & \cr
{\it value-typespec\/}::$=$ {\it typespec\/}  $\vert$ \paren{{\tt values} . {\it arg-typespec-list\/}} & \cr
{\it dimensions\/}::$=$ {\it integer\/} $\vert$ {\tt *} $\vert$ 
\paren{\star{\curly{integer $\vert$ {\tt *} }}} & \cr
{\it size\/}::$=$ {\it integer\/} & \cr
{\it integer-limit\/}::$=$ {\it integer\/} $\vert$ {\tt *}  
$\vert$  ({\it integer\/}) & \cr
{\it fixnum-limit\/}::$=$ {\it fixnum\/} $\vert$ {\tt *}  
$\vert$  ({\it fixnum\/}) &\cr
{\it rational-limit\/}::$=$ {\it rational\/} $\vert$ {\tt *}  $\vert$  ({\it rational\/})\cr
{\it float-limit\/}::$=$ {\it float\/} $\vert$ {\tt *}  $\vert$  ({\it float\/})\cr
{\it short-float-limit\/}::$=$ {\it short-float\/} $\vert$ {\tt *}  $\vert$  ({\it short-float\/})\cr
{\it single-float-limit\/}::$=$ {\it single-float\/} $\vert$ {\tt *}  $\vert$  ({\it single-float\/})\cr
{\it double-float-limit\/}::$=$ {\it double-float\/} $\vert$ {\tt *}  $\vert$  ({\it double-float\/})\cr
{\it long-float-limit\/}::$=$ {\it long-float\/} $\vert$ {\tt *}  $\vert$  ({\it long-float\/})\cr
}}
\caption{Definitions for Syntax for Type Specifiers}             
\endfig
 
%% 4.2.0 1         
If a type specifier is a {\datatype list}, the {\word car}
of the {\datatype list} 
is a {\datatype symbol}, and the rest of the {\datatype list} 
is subsidiary
{\word type} information.  The subsidiary items may be
unspecified.  The unspecified subsidiary items are indicated
by writing @f[*]\rm.  For example, to completely specify
a {\datatype vector}, the {\word type} of the elements
and the length of the {\datatype vector}, must be present.
 
@lisp
 (vector double-float 100)
@endlisp
To leave the length unspecified:
 
@lisp
 (vector double-float *)
@endlisp
To leave the element type unspecified:
 
@lisp
 (vector * 100)
@endlisp
Suppose that two type specifiers are the same except that the first
has a @f[*] where the second has a more explicit specification.
Then the second denotes a {\word subtype} 
of the {\word type} denoted by the first.
 
%% 4.2.0 2
If a {\datatype list}
has one or more unspecified items at the end, those items
may be dropped.
If dropping all occurrences of @f[*] results in a singleton {\datatype list},
then the parentheses may be dropped as well (the list may be replaced
by the {\datatype symbol} in its {\word car}).  
For example,                       
{\tt (vector double-float *)}                    
may be abbreviated to {\tt (vector double-float)},               
and {\tt (vector * *)} may be abbreviated to {\tt (vector)} 
and then to 
{\tt vector}.
 
 
A list of possible type specifier {\datatype lists} follows:
\beginlist                     
%% 4.3.0 1
\itemitem
{\tt (satisfies {\arg predicate-name})} 
 
This denotes
the set of all {\word objects} 
that satisfy the predicate {\arg predicate-name},
which must be a {\datatype symbol} 
whose global {\word function} definition is a one-argument
predicate.
A name is required for {\arg predicate-name}; {\word lambda-expressions} 
are not allowed.                                     
For example, the type {\tt (satisfies numberp)} is the
same as the type {\datatype number}.
The call {\tt (typep x '(satisfies p))} 
results in applying @f[p] to @f[x]
and returning @f[t] if the result is true and @nil\ if the result is false.
%% 4.3.0 2                                   
For example, the type {\datatype string-char} could be defined as
 
@lisp
 (deftype string-char () '(and character (satisfies string-char-p)))
@endlisp
 
%% 4.4.0 3
\itemitem
{\tt (member {\arg object1} {\arg object2} ...)}
 
This denotes the set
containing the named {\arg objects}. An {\word object} is of
this {\word type} 
if and only if it is @Funref[eql] to one of the specified {\arg objects}.
 
%% 4.4.0 4              
\itemitem
{\tt (not {\arg type})}
 
This denotes the set of all {\word objects} that
are not of the type {\arg type}.
                                      
%% 4.4.0 5               
\itemitem{\tt (and {\arg type1} {\arg type2} ...)}
  
This denotes the set of all {\word objects} of the
{\word type} determined by the intersection of 
{\arg type1}, {\arg type2},....
                            
%% 4.4.0 7 
\itemitem{\tt (or {\arg type1} {\arg type2} ...)}
                               
This denotes the set of all {\word objects} of the
{\word type} determined the union of {\arg type1}, {\arg type2},....
For example, the type {\datatype list} 
by definition is the same as
{\tt (or null cons)}.  Also, the value 
returned by                                                             
@Funref[position] is of type {\tt (or null (integer 0 *))}
(either @nil\ or a non-negative {\datatype integer}).
                                                 
%% 4.6.0 3                           
\itemitem{\tt (integer {\arg low} {\arg high})}
                             
This denotes the {\datatype integers} between
{\arg low} and {\arg high}.  {\arg Low} and {\arg high}
must each be {\datatype integers}, a {\datatype list} 
of an {\datatype integer}, or unspecified.
An {\datatype integer} is an inclusive limit,
a {\datatype list} of an {\datatype integer} is an exclusive limit, and
@f[*] means that a limit does not exist
and so effectively denotes minus or plus infinity, respectively.
{\datatype Fixnum} is a name        
for {\tt (integer {\arg smallest} {\arg largest})} 
for implementation-dependent     
values of {\arg smallest} and {\arg largest}.
The type {\tt (integer 0 1)}
has the name {\datatype bit}.
 
%% 4.6.0 4
                               
\itemitem{\tt (mod {\arg n})}
                                                         
This denotes the set of non-negative {\datatype integers} less than {\arg
n}.                                                  
This is equivalent to {\tt (integer 0 {\it n}-1)}
or to {\tt (integer 0 ({\it n}))}.
 
%% 4.6.0 5                             
\itemitem{\tt (signed-byte {\arg s})}
 
This denotes the set of {\datatype integers} that can be represented
in two's-complement form in a byte of {\arg s} bits.  This is
equivalent to                                    
{\tt (integer $-2↑{s-1} 2↑{s-1}-$1)}.             
The type {\datatype signed-byte} or the type {\tt (signed-byte *)} 
is the same as the type {\datatype integer}.
 
%% 4.6.0 6                               
\itemitem{\tt (unsigned-byte {\arg s})}
 
This denotes the set of non-negative {\datatype integers} that can be
represented in a byte of {\arg s} bits.  This is equivalent to 
{\tt (mod $2↑s$)},
that is, {\tt (integer 0 $2↑s-$1)}.
The type {\datatype unsigned-byte} or 
the type {\tt (unsigned-byte *)} is the same as
the type {\tt (integer 0 *)}, the set of non-negative {\datatype integers}.
                                                  
%% 4.6.0 7                            
\itemitem{\tt (rational {\arg low} {\arg high})}
 
This denotes the {\datatype rationals} between
{\arg low} and {\arg high}.  {\arg Low} and {\arg high}
must each be a {\datatype rational}, a {\datatype list} of a {\datatype
rational}, or unspecified.
A {\datatype rational} is an inclusive limit,
a {\datatype list} of a {\datatype rational} is an exclusive limit, and
@f[*] means that a limit does not exist
and so denotes minus and plus infinity, respectively.
                                               
%% 4.6.0 8                         
%% 4.6.0 9
\itemitem{\tt (float {\arg low} {\arg high})}
\itemitem{\tt (short-float {\arg low} {\arg high})}
 
\itemitem{\tt (single-float {\arg low} {\arg high})}
 
\itemitem{\tt (double-float {\arg low} {\arg high})}
 
\itemitem{\tt (long-float {\arg low} {\arg high})}
 
                                                   
These denote the set of {\datatype floating}-point numbers between
{\arg low} and {\arg high}.  {\arg Low} and {\arg high}
must each be a {\datatype floating}-point number, 
a {\datatype list} of a {\datatype floating}-point number,
or unspecified. A {\datatype floating}-point number 
is an inclusive limit, a {\datatype list} of a
{\datatype floating}-point number is an exclusive limit, and
@f[*] means that a limit does not exist
and so denotes minus and plus infinity, respectively.
 
In the case of the types {\tt short-float}, {\tt single-float},
{\tt double-float}, or {\tt long-float},
if a limit is a {\datatype floating}-point   
number (or a {\datatype list} of one), 
it must be one of the appropriate format.
 
%% 4.6.0 10                           
\itemitem{\tt (string {\arg size})}
         
This denotes the same type as               
the type {\tt (array string-char ({\arg size}))}: 
the set of {\datatype strings} of size {\arg size}.
 
 
%% 4.6.0 11                                  
\itemitem{\tt (simple-string size {\arg size})}
 
This denotes the same type 
as the type {\tt (simple-array string-char ({\arg size}))}: the set of 
{\datatype simple-strings} of size {\arg size}.
 
%% 4.6.0 12                               
\itemitem{\tt (bit-vector {\arg size})}
                                                        
This denotes the same type as the type {\tt (array bit ({\arg size}))}:
the set of {\datatype bit-vectors} of size {\arg size}.
 
%% 4.6.0 13                           
\itemitem{\tt (simple-bit-vector {\arg size})}
 
This denotes the same type as the type
{\tt (simple-array bit ({\arg size}))}: the set of 
{\datatype simple-bit-vectors} of size {\arg size}.
 
%% 4.5.0 6
%% 4.5.0 7
\itemitem{\tt (array {\arg element-type dimensions})}
 
This denotes the set
of {\datatype arrays\/}
whose elements are all of type {\arg element-type}
and whose dimensions are {\arg dimensions}.
{\arg Element-type} must be a valid type specifier or unsupplied.
{\arg Dimensions} must be a non-negative {\datatype integer},
which is the number
of dimensions, or a {\datatype list} of non-negative {\datatype integers}
representing the length of each dimension (any dimension
may be unsupplied instead), or it may be unsupplied.
\issue{ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS:UNIFY-UPGRADING}
The following will be left out:
 
For declaration purposes, this {\word type} encompasses those 
{\datatype arrays\/}
that can result by supplying {\arg element-type} as the element type
to the function @Funref[make-array]\rm; this may be different
from what the {\word type} means for discrimination purposes.
For example:
 
@lisp
 (array integer 3)       ;Three-dimensional arrays of integers
 (array integer (* * *)) ;Three-dimensional arrays of integers
 (array * (4 5 6))       ;4-by-5-by-6 arrays
 (array character (3 *)) ;Two-dimensional arrays of characters that have 
                         ;three rows
 (array short-float @empty)   ;Zero-rank arrays of short-floats
@Endlisp                    
\endissue{ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS:UNIFY-UPGRADING}
 
 
 
\issue{ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS:UNIFY-UPGRADING}
{\tt (array *)} refers to all {\datatype arrays\/} 
regardless of element type, {\tt (array {\arg type-specifier})}
refers only to those {\datatype arrays\/} 
that can result from giving {\arg type-specifier} as the
{\tt :element-type} argument to {\function make-array}.  
\endissue{ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS:UNIFY-UPGRADING}
Note that the type {\tt (array t)}     
is a subset of the type {\tt (array *)}.
The reason is that the type {\tt (array t)} is the set of {\datatype arrays\/} 
that can
hold any {\word object} (the elements are of type 
{\datatype t},
which includes all {\word objects}).  
On the other hand, the type {\tt (array *)}
is the set of all {\datatype arrays\/} whatsoever, including for example
{\datatype arrays\/} that can hold only {\datatype characters}. 
Now                                                                   
the type {\tt (array character)} is not a subset of the type {\tt (array t)}; 
the two sets                                              
are {\word disjoint} because the type {\tt (array character)} is not the
set of all {\datatype arrays\/} that can hold 
{\datatype characters}, but rather the set of
{\datatype arrays\/} 
that are specialized to hold precisely {\datatype characters} and no
other {\word objects}. 
\issue{ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS:UNIFY-UPGRADING}
The following will be deleted:
 
The following expression cannot be used to determine if
array @f[foo] can hold a {\datatype character}:
 
@lisp
 (typep foo '(array character))
@endlisp
The following expression can be used to determine if
array @f[foo] can hold a {\datatype character}:
 
@lisp
 (subtypep 'character (array-element-type foo))
@endlisp
\endissue{ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS:UNIFY-UPGRADING}
 
%% 4.5.0 8                                   
\itemitem{\tt (simple-array {\arg element-type dimensions})}
                   
This is equivalent
to the type {\tt (array {\arg element-type} {\arg dimensions})} 
except that it additionally
specifies that the {\datatype array\/}
{\word objects} are {\datatype simple-arrays}.
             
\issue{ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS:UNIFY-UPGRADING}
{\tt (simple-array *)} refers to all {\datatype simple-arrays\/} 
regardless of element type, {\tt (simple-array {\arg type-specifier})}
refers only to those {\datatype simple-arrays\/} 
that can result from giving {\arg type-specifier} as the
{\tt :element-type} argument to {\function make-array}.  
\endissue{ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS:UNIFY-UPGRADING}
 
%% 4.5.0 9
\itemitem{\tt (vector {\arg element-type} {\arg size})}
 
This denotes the set of specialized
one-dimensional {\datatype arrays\/}                        
whose elements are all of type {\arg element-type}
and whose lengths are size {\arg size}.  This is equivalent to
the type {\tt (array {\arg element-type} ({\arg size}))}.
For example:
 
@lisp
 (vector double-float)	;Vectors of double-format floating-point numbers
 (vector * 5)		;Vectors of length 5
 (vector t 5)		;General vectors of length 5
 (vector (mod 32) *)	;Vectors of integers between 0 and 31
@Endlisp                                                     
The types {\tt (vector string-char)} and {\tt (vector bit)}
have the names {\datatype string} and {\datatype bit-vector}.
Every implementation of @clisp\ must provide distinct representations for
these as distinct specialized {\word types}.
 
\issue{ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS:UNIFY-UPGRADING}
{\tt (vector *)} refers to all {\datatype vectors\/} 
regardless of element type, {\tt (vector {\arg type-specifier})}
refers only to those {\datatype vectors\/} 
that can result from giving {\arg type-specifier} as the
{\tt :element-type} argument to {\function make-array}.  
\endissue{ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS:UNIFY-UPGRADING}
 
%% 4.5.0 10                            
\itemitem{\tt (simple-vector {\arg size})}
 
This is the same                
as the type {\tt (vector t {\arg 
size})} except that it additionally specifies
that its elements are {\datatype simple-vectors}.
 
%% 4.5.0 11                           
\itemitem{\tt (complex {\arg type})}
 
Every element of this {\word type} is a
{\datatype complex\/} number whose real part 
and imaginary part are each of type {\arg type}.
This {\word type} encompasses those 
{\datatype complex\/} numbers
that can result by giving numbers of the specified {\word type}
to @Funref[complex]\rm.
\issue{ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS:UNIFY-UPGRADING}
The following will be deleted:
 
This may be different
from what the {\word type} means for discrimination purposes.
For example, Gaussian integers might be   
described as the type {\tt (complex integer)}, even in implementations
where giving two {\datatype integers} to {\function complex\/} results
in an {\word object} of type {\tt (complex rational)}.
\endissue{ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS:UNIFY-UPGRADING}
 
%% 2.1.4 3
The type of a specific {\datatype complex\/} number is indicated by a list
of the word @f[complex] and the type of the components; for example,
a specialized representation for {\datatype complex\/} 
numbers with {\datatype short-float}
parts would be of type {\tt (complex short-float)}.  The type 
{\datatype complex\/}
encompasses all complex representations.
 
\issue{ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS:UNIFY-UPGRADING}
{\tt (typep {\arg object} '(complex {\arg type-specifier}))}
refers to all {\datatype complex\/} numbers that can result from 
giving {\datatype numbers} of type {\arg type-specifier}
to the function {\function complex\/}, plus all other 
{\datatype complex\/} numbers 
of the same specialized representation.      
Both the real and the imaginary parts of any such 
{\datatype complex\/} number must 
satisfy:
 
{\tt  (typep {\arg realpart}|{\arg imagpart} '{\arg type-specifier})}
 
\endissue{ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS:UNIFY-UPGRADING}
 
%% 4.5.0 12                                    
\itemitem{\tt (function ({\arg arg1-type} {\arg arg2-type} ...) 
{\arg value-type})}
 
\issue{FUNCTION-TYPE}
The list form of the type {\datatype function}
may be used only for declaration and not for discrimination.
\endissue{FUNCTION-TYPE}
Every element of this {\word type} is
a {\word function} that accepts arguments at least of the
types   
specified by the {\arg argj-type} forms and returns a value that is a
member of the types specified by the {\arg value-type} form.  The
@optional, @rest, @key, 
\issue{FUNCTION-TYPE-KEY-NAME}
and @allowotherkeys\
\endissue{FUNCTION-TYPE-KEY-NAME}
markers may appear in the list of argument 
types. 
\issue{FUNCTION-TYPE-KEY-NAME}
The @key\ parameters 
should be supplied as lists of the form {\tt (keyword type)}.  
The {\tt keyword} must
be a valid keyword-name 
symbol and must be supplied in the actual arguments of a
call. This is usually a {\datatype symbol} in the {\tt keyword} package
but can be any {\datatype symbol}.
The @allowotherkeys\ declarations are interpreted as follows:
when @key\ is given in a
{\tt function} type specifier lambda list, 
it is safe to assume that the @key s given
are exhaustive unless @allowotherkeys\ is present. 
@allowotherkeys\ is an indication 
that other keyword arguments may actually be
supplied and, if supplied, may be used. 
For example,
the type of the function {\function make-list} could be declared as:
 
@lisp
 (function make-list ((integer 0) &key (:initial-element t)) list)
@endlisp
\endissue{FUNCTION-TYPE-KEY-NAME}
 
The {\arg value-type} may be a {\tt values} 
type specifier in order to indicate the
{\word types} of multiple values.
 
%% 4.5.0 13
For example, the function @Funref[cons] is of type 
{\tt (function (t t) cons)},
because it can accept any two arguments and always returns a {\word
cons}.
{\function cons} is                                        
also of type {\tt (function (float string) list)}, 
because it can
accept a {\datatype floating}-point number 
and a {\datatype string} (among other things), and its
result is always of type {\datatype list}            
(in fact a {\word cons} is never {\datatype null},
but that does not matter for this type declaration).
@Funref[truncate] is of type 
{\tt (function (number number) (values number number))}, 
as well as of type
{\tt (function (integer (mod 8)) integer)}.
 
%% 4.5.0 14                                                    
\itemitem{\tt (values {\arg value1-type} {\arg value2-type} ...)}
 
This type specifier may be used only       
as the {\arg value-type} in a {\tt function} type specifier or in
@Specref[the]\rm. It is used to specify individual {\word types} when
multiple values are involved.
The
@optional, @rest, and @key\ markers may appear in the {\arg value-type} list;
they indicate the parameter list of a
{\word function} that, 
when given to @Specref[multiple-value-call] along with
the values, would be suitable for receiving those values.
 
\endlist
 
 
%% 4.7.0 1
New type specifiers can come into existence in two ways.
\beginlist
\itemitem{\bull} Defining a structure or class
with @Macref[defstruct] or {\function defclass} automatically
causes the name of the structure or class to be a new type specifier 
{\datatype symbol}.
\itemitem{\bull} {\function deftype} can be used to define new type specifier
abbreviations.
\endlist
 
 
Figure {\chapno--\the\capno}
lists the {\word tools} that are applicable to types and declarations.
 
\boxfig
{\dimen0=.75pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil\tabskip \dimen0 plus 1fil&#\hfil\tabskip \dimen0 plus
1fil&#\hfil\cr 
\noalign{\vskip -9pt}                               
{\tt deftype }&{\tt  coerce }&{\tt  type-of }\cr
{\tt declare }&{\tt  locally }&{\tt  proclaim }\cr
{\tt the }&{\tt  defstruct }&\cr
 
\noalign{\vskip -9pt} }} 
\caption{Type and declaration tools}  
\endfig
 
\beginsubsubsection{Type Upgrading}
\issue{ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS:UNIFY-UPGRADING}
When type specifiers are used to declare {\word objects} to be of a certain
{\word type}, they are said to be used   
for declaration.  A type specifier used for declaration
can be the 
{\tt :element-type} argument to  
{\function make-array}, the {\arg result-type}
 argument to {\function coerce}, 
an argument to the special form {\function the},
or an argument to {\function declare}. 
 
An {\word object} declared to be of a certain
 {\word type} may not satisfy 
{\function typep} with that type specifier.   
 This is permissible because an implementation 
is required only to construct the
 result out of the most specialized {\word type} that can
 accommodate elements of the {\word type} supplied as the argument
to the {\tt :element-type} named argument to {\function make-array}.
That is, an implementation may only provide a 
 very small number of {\word types} for storing 
{\datatype  arrays\/}, 
 and it is permitted to upgrade any {\word type} request into 
 one of its built-in repertoire.
One type specifier with 
 this property is  {\tt (array {\arg type-specifier})}
 for various implementation-dependent values of {\arg type-specifier}.  
Another type specifier with this property is 
{\tt (complex {\arg type-specifier})}.
 
 
{\word Type} upgrading implies a movement upwards in the type 
hierarchy lattice.  In the case of {\datatype arrays\/}
the {\arg type-specifier} must be
a {\word subtype} of 
{\tt (upgraded-array-element-type '{\arg type-specifier})}.  
In the case of {\datatype complex\/} numbers, the 
{\arg type-specifier} must be a {\word subtype} of 
{\tt (upgraded-complex-part-type {\arg type-specifier})}.
If {\arg type-specifier1} is a {\word subtype} of {\arg type-specifier2}, then
{\tt (upgraded-array-element-type '{\arg type-specifier1})}
must also be a {\word subtype} of
{\tt (upgraded-array-element-type '{\arg type-specifier2})}.  
Two {\word disjoint types} can be upgraded into 
the same thing.
 
See {\function array-element-type}. 
 
Upgrading an {\datatype array\/} element {\word type} is independent of any 
other property of {\datatype arrays\/}, 
such as {\word rank}, adjustability, {\word fill-pointers}, or 
displacement. 
The reason {\word rank} is included is because
it would not be consistently possible to displace {\datatype arrays\/} 
to those of 
differing {\word rank} if {\word rank} were not included.
 
\endissue{ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS:UNIFY-UPGRADING}
 
\endsubsubsection%{Type Upgrading}
 
 
\endsubSection%{Type Specifiers}

∂02-Mar-89  1151	X3J13-mailer 	Re: cs proposal comments  
Received: from ti.com by SAIL.Stanford.EDU with TCP; 2 Mar 89  11:51:39 PST
Received: by ti.com id AA08145; Thu, 2 Mar 89 13:50:34 CST
Received: from Kelvin by tilde id AA05068; Thu, 2 Mar 89 13:39:29 CST
Message-Id: <2813859524-5211323@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Thu, 2 Mar 89  13:38:44 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: Thom Linden <baggins@IBM.com>
Cc: x3j13@sail.stanford.edu
Subject: Re: cs proposal comments
In-Reply-To: Msg of Thu, 02 Mar 89 02:20:21 PST from Thom Linden <baggins@IBM.com>

> >>   Never mind that; the real question is why do you want the standard to not
> >>   specify the meaning of tabs and form-feeds in source files?
> >>
> I don't have my CLtL with me but I don't think a meaning is given
> to the semi-standard characters (unless we consider them self defining?)

I'm talking about page 336 of CLtL which specifies that the reader treats
#\TAB and #\PAGE as whitespace.  Section A.22.1.1 of the February 21 document
specifies deleting the mention of these.

> The form label:registry is given on p38 where for #\, "In particular,
> an implementation may support names of the form label:registry."
> It could do with repeating on p35 (name-char, char-name).

"_may_ support"?  It seems like either this should be part of the standard or
not.  What does CHAR-NAME return for non-standard characters if the
implementation doesn't support this?  If you are going to permit referencing
names that way, then what do we need registries for?  Also, the sentence
quoted is in the context of non-graphic characters.  What about names for
non-standard graphic characters?  Do standard graphic characters have names?

∂02-Mar-89  1632	X3J13-mailer 	minor comments on the character proposal 
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 2 Mar 89  16:31:53 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 549744; Thu 2-Mar-89 19:29:32 EST
Date: Thu, 2 Mar 89 19:29 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: minor comments on the character proposal
To: Thom Linden <baggins@IBM.com>
cc: x3j13@SAIL.STANFORD.EDU
In-Reply-To: <890222.120815.baggins@almvma>
Message-ID: <19890303002938.9.MOON@EUPHRATES.SCRC.Symbolics.COM>

These comments are not an official response to your request for a vote.

Here are some comments on the character proposal version of 21 Feb 89.
I believe these are all merely editorial, but if they are matters of
disagreement I'd like to know.

p.29, describing character attributes: It needs to be clarified that
these notes apply to all implementation-defined character attributes,
not just to attributes that might be provided for compatibility with
the earlier version of Common Lisp.

Some of these notes have not been consistently reflected elsewhere in
the proposal, for example, page 31 seems to say that the only difference
between char-equal and char-= involves alphabetic case, whereas page 29
says that char-= compares all attributes but char-equal compares an
implementation-defined set of attributes (page 29 is correct).
Similarly, where p.31 says "if the codes of two characters differ, then
they are different", it should instead say "if the codes or
implementation-defined attributes (if any) of two characters differ,
then they are different."

Two of the notes on p.29 refer to char-int and int-char, which you are
proposing to remove, so those notes should be removed.

p.33, 35: Under find-char, char-registry-name, and char-label you
indicate that registry names and labels are strings.  In fact they
are symbols now, these places need to be updated.

p.38: Where it says "an implementation may support names of the
form label:registry", I believe this to be a typo for "registry:label".
The colon is evidently being used by analogy to packages, so the
registry name should precede the label, just as the package name
precedes the symbol name.

∂02-Mar-89  1909	X3J13-mailer 	cs proposal and straw vote
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 2 Mar 89  19:09:09 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 549840; Thu 2-Mar-89 22:06:27 EST
Date: Thu, 2 Mar 89 22:06 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: cs proposal and straw vote
To: Dan L. Pierson <pierson@mist.encore.com>
cc: baggins@ibm.com, x3j13@SAIL.STANFORD.EDU
In-Reply-To: <8903012050.AA11442@mist.>
Message-ID: <19890303030636.7.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Wed, 01 Mar 89 15:49:59 EST
    From: Dan L. Pierson <pierson@mist.encore.com>

	    Issue: CHAR-INT-ONLY-USEFUL-WHEN-ATTRIBUTES-SUPPORTED
	    Problem: CHAR-INT behavior is CHAR-CODE unless implementation
	      defined attributes are supported.
	    Proposal:
		      Remove CHAR-INT
    IF: Moon agrees that this is sufficient for hashing (or I'm convinced that
    he's wrong :-)).

This is actually an interesting issue.  I was going to say that CHAR-INT
is not needed, because you can use SXHASH.  After all, in any reasonable
implementation SXHASH of a character would just return the CHAR-INT, and
the only difference would be the extra cost of a type dispatch, which
might even be compiled out in some cases.  Then I tried the most
reasonable implementation I know and found that SXHASH and CHAR-INT did
not return the same value.  So then I did what I should have done at the
beginning, and read the documentation of SXHASH.  SXHASH doesn't just
return any useful hash code, it returns one that remains constant for
all time, within "the same" implementation.  This means that in any
implementation that dynamically assigns numeric encodings of any
character attribute, SXHASH cannot be the same as CHAR-INT.  Genera, for
example, allows user-defined character registries and user-defined
character style attributes, and thus dynamically assigns the numeric
encoding of both character code and character style.

There are many applications of hashing for which the perpetual equality
properties of SXHASH are unwanted, and the associated efficiency cost
is undesired.

So now my opinion is that CHAR-INT should be retained, but INT-CHAR
and its shadow in the COERCE function should be removed.

	What do STRING-LESSP, etc. mean for non-standard-character strings?

Isn't STRING-LESSP defined in terms of CHAR-LESSP?  CHAR-LESSP has "the
results are unspecified" for two characters in different registries, I
assume, which means that STRING-LESSP of two strings of extended
characters in the same registry is perfectly well defined, and of
characters in different registries returns either true or false, but is
harmless.

∂02-Mar-89  1929	X3J13-mailer 	answer to request for comments on comments on comments on characters   
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 2 Mar 89  19:28:57 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 549853; Thu 2-Mar-89 22:26:02 EST
Date: Thu, 2 Mar 89 22:26 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: answer to request for comments on comments on comments on characters
To: Thom Linden <baggins@IBM.com>
cc: Common Lisp mailing <x3j13@SAIL.STANFORD.EDU>
In-Reply-To: <890222.100432.baggins@almvma>
Message-ID: <19890303032620.8.MOON@EUPHRATES.SCRC.Symbolics.COM>

In your comments on my comments on the 1 Jan 89 character proposal,
you asked some questions.  Here are my answers.  These are personal
answers rather than Symbolics' official position.

    Date: Wed, 22 Feb 89 10:04:32 PST
    From: Thom Linden <baggins@IBM.com>

    >>   From: "David A. Moon" <Moon@SCRC-STONY-BROOK.ARPA>
    >>   Subject: Comments on the Character proposal dated January 1, 1989
    >>
    >>   The default for :ELEMENT-TYPE has two viable choices that I can see
    >>   both and let people vote:
    >>
    >>     (1) CHARACTER.  This matches the behavior of MAKE-STRING and friends,
    >>     (2) The most natural type for the particular pathname being opened.
    >>   The relationship of option 2 to :ELEMENT-TYPE :DEFAULT (a feature that
    >>   already exists in Common Lisp) needs to be clarified.  Perhaps they
    >>   are the same.

    The same?  I don't understand.  For example, I can imagine the
    element-type default as base-character and the external format
    defaulted to either an ASCII or EBCDIC encoding.

I think you misunderstood.  I was suggesting that perhaps the default
value for the :ELEMENT-TYPE option to OPEN should be the symbol
:DEFAULT.  This doesn't relate to the external coding format as far as I
can see, except for whatever niceness we see in having the default
value for both :ELEMENT-TYPE and :EXTERNAL-CODED-CHARACTER-FORMAT be the
symbol :DEFAULT.

I see that in the 21 Feb 89 proposal you have made the default value for
the :ELEMENT-TYPE option to OPEN be implementation dependent, but not
:DEFAULT.  In fact they are different, because :DEFAULT can open in
either a character type or an integer type, but (the unnamed) default
can only open in a character type.  I can live with what you have
proposed, although I still believe that requiring :ELEMENT-TYPE to
default to CHARACTER might be better, and I'm a little concerned about
having a default for which there is no name within the language.  I'd
also like to hear opinions on whether we need two different ways to say
"the most natural type for the particular pathname being opened", with
one of them restricted to subtypes of CHARACTER and the other
unrestricted.

More importantly, though, I think people should be given the choice
of voting between the two options mentioned above (as well as any other
options that garner some support, if there are any).  As it stands
the :ELEMENT-TYPE option to OPEN isn't in the straw ballot at all,
there's just a change in the back of the proposal.

    >>   Also the following promise from 14 November did not show up in the report:
    >>
    >>     >>     There should be a name for the "natural" encoding and there should be a
    >>     >>     specification of the properties of the natural encoding that a programmer
    >>     >>     can rely on.  Suggestions for the name include :BASE, :NATURAL, and
    >>     >>     :INTERCHANGE.  The definition probably involves the concept of data
    >>     >>     interchange with non-Lisp programs on the same system.
    >>
    >>     This will be added to the revision.

    I lied.  No one came up with the 'properties' of such an encoding.
    Do you have some text to suggest?

I'm not sure if your :DEFAULT for :EXTERNAL-CODED-CHARACTER-FORMAT is
intended to be "natural" as well as "default", or not.  I'm afraid
I haven't been able to come up with a good description of what it
means to be "natural", though.  Perhaps I'm familiar with too many
oddball systems, which makes me more scared of trying to define the
concept than would be someone who only knew Unix.  I think we can
safely drop this issue without much harm to the language.

    >>   No particular page -- We agree with the deprecation or deletion of the two
    >>   particular character attributes defined by CLtL, but not with the
    >>   deprecation of the whole concept of character attributes.  In fact on page
    >>   20 you say "characters are uniquely distinguished by their codes," which
    >>   makes it impossible to have character attributes at all.  The language must
    >>   define how conforming programs should be written so that they will work
    >>   both in implementations with character attributes and in implementations
    >>   without them.  For example, the value of (eql x (code-char (char-code x)))
    >>   is unspecified.  Another thing that needs to be said is that the exact
    >>   character operations (char=, string=, etc.) respect all character
    >>   attributes, while the inexact character operations (char-equal,
    >>   string-equal, etc.) respect or ignore each character attribute in an
    >>   implementation-defined but consistent fashion.  

This has improved in the 21 Feb 89 version, but I think more a explicit
statement is still required.  You are welcome to borrow the language
("exact", "inexact") that I used just above.

							 Some of what you say on
    >>   page 44 about attributes in general needs to be part of the spec, not
    >>   deprecated.  I would retain everything on that page except for INT-CHAR and
    >>   the last bullet (referring to bits and fonts), and I would add a remark
    >>   that FIND-SYMBOL and INTERN respect character attributes.  If you want,
    >>   perhaps I or someone else at Symbolics can provide exact text for what
    >>   to say about character attributes that you could insert into your report.

    I moved the attribute list previously in Appendix B back into the
    description of characters.  Let me know what text you would like
    to see for FIND-SYMBOL and INTERN and I'll add it to the list.

After "It is implementation dependent whether attributes are removed
from symbol names by READ" (and by the way, in this and the preceding
bullet I believe "whether" shoudl be changed to "which", since an
implementation with several character attributes might have good reason
to remove some and retain others), I would add "The functions FIND-SYMBOL
and INTERN do not remove character attributes."

∂02-Mar-89  1941	CL-Characters-mailer 	Really about TYPEP failures: Comments on the Character proposal dated January 1, 1989   
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 2 Mar 89  19:41:42 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 549857; 2 Mar 89 22:39:01 EST
Date: Thu, 2 Mar 89 22:39 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Really about TYPEP failures: Comments on the Character proposal dated January 1, 1989
To: Robert W. Kerns <RWK@FUJI.ILA.Dialnet.Symbolics.COM>
cc: Jon L White <jonl@lucid.com>, Baggins@IBM.COM, CL-Characters@SAIL.STANFORD.EDU,
    X3J13@SAIL.STANFORD.EDU, Common-Lisp-Implementors@Symbolics.COM, KMP@Symbolics.COM,
    Palter@Symbolics.COM
In-Reply-To: <19890204142708.2.RWK@CALVARY.ILA.Dialnet.Symbolics.COM>
Supersedes: <19890303023922.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Comments: Removed % signs
Message-ID: <19890303033902.9.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Sat, 4 Feb 89 09:27 EST
    From: Robert W. Kerns <RWK@FUJI.ILA.Dialnet.Symbolics.COM>

    Legitimate operations on BASE-CHARACTER do not
    produce characters in (AND CHARACTER (NOT BASE-CHARACTER)).

I'm not sure which programs written using symbols in the LISP package
are "legitimate operations" and which are not.  However, I didn't see
anything in the 21 Feb 89 proposal that says that CHAR-UPCASE of
a BASE-CHARACTER is necessarily a BASE-CHARACTER, for example.
That doesn't sound unreasonable, though; should it be added?

∂03-Mar-89  0004	X3J13-mailer 	cs comments
Received: from IBM.COM by SAIL.Stanford.EDU with TCP; 3 Mar 89  00:03:57 PST
Date: Thu, 02 Mar 89 17:19:25 PST
From: Thom Linden <baggins@IBM.com>
To: Common Lisp mailing <x3j13@sail.stanford.edu>
Message-ID: <890302.171925.baggins@almvma>
Subject: cs comments

>>   From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
>>   Subject: minor comments on the character proposal
>>
>>   These comments are not an official response to your request for a vote.
>>
>>   Here are some comments on the character proposal version of 21 Feb 89.
>>   I believe these are all merely editorial, but if they are matters of
>>   disagreement I'd like to know.
>>
>>   p.29, describing character attributes: It needs to be clarified that
>>   these notes apply to all implementation-defined character attributes,
>>   not just to attributes that might be provided for compatibility with
>>   the earlier version of Common Lisp.

Ok.

>>
>>   Some of these notes have not been consistently reflected elsewhere in
>>   the proposal, for example, page 31 seems to say that the only difference
>>   between char-equal and char-= involves alphabetic case, whereas page 29
>>   says that char-= compares all attributes but char-equal compares an
>>   implementation-defined set of attributes (page 29 is correct).
>>   Similarly, where p.31 says "if the codes of two characters differ, then
>>   they are different", it should instead say "if the codes or
>>   implementation-defined attributes (if any) of two characters differ,
>>   then they are different."

The intent was that p29 defined all the modified behaviors when
implementation-defined attributes were supported.  I could repeat these
notes (through modified text) at each of the referenced locations or
make the intent of p29 stronger.  Which do you feel is clearer?

>>
>>   Two of the notes on p.29 refer to char-int and int-char, which you are
>>   proposing to remove, so those notes should be removed.

Correct.

>>
>>   p.33, 35: Under find-char, char-registry-name, and char-label you
>>   indicate that registry names and labels are strings.  In fact they
>>   are symbols now, these places need to be updated.

Right.

>>
>>   p.38: Where it says "an implementation may support names of the
>>   form label:registry", I believe this to be a typo for "registry:label".
>>   The colon is evidently being used by analogy to packages, so the
>>   registry name should precede the label, just as the package name
>>   precedes the symbol name.
>>

Ok.


∂03-Mar-89  0913	X3J13-mailer 	cs comments
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 3 Mar 89  09:13:20 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 550140; Fri 3-Mar-89 12:10:42 EST
Date: Fri, 3 Mar 89 12:10 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: cs comments
To: Thom Linden <baggins@IBM.com>
cc: Common Lisp mailing <x3j13@SAIL.STANFORD.EDU>
In-Reply-To: <890302.171925.baggins@almvma>
Message-ID: <19890303171050.3.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Thu, 02 Mar 89 17:19:25 PST
    From: Thom Linden <baggins@IBM.com>

    >>   From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
    >>   Subject: minor comments on the character proposal
    >>
    >>   Some of these notes have not been consistently reflected elsewhere in
    >>   the proposal, for example, page 31 seems to say that the only difference
    >>   between char-equal and char-= involves alphabetic case, whereas page 29
    >>   says that char-= compares all attributes but char-equal compares an
    >>   implementation-defined set of attributes (page 29 is correct).
    >>   Similarly, where p.31 says "if the codes of two characters differ, then
    >>   they are different", it should instead say "if the codes or
    >>   implementation-defined attributes (if any) of two characters differ,
    >>   then they are different."

    The intent was that p29 defined all the modified behaviors when
    implementation-defined attributes were supported.  I could repeat these
    notes (through modified text) at each of the referenced locations or
    make the intent of p29 stronger.  Which do you feel is clearer?

I feel strongly that in the eventual language standard, it will not be
acceptable to have two sections that speak inconsistently about the same
thing, with the reader told that one section takes precedence over the
other.  Thus in the eventual document, this kind of information must be
repeated (at least by reference) at each occurrence.  For example, you
can't say in one place "char-equal is the same as char-= except it ignores
alphabetic case" and then say in another place "the other description
of char-equal was simplified for your comfort and convenience, the real
description is char-equal is the same as char-= except it ignores
alphabetic case and some implementation-defined character attributes."

I'm not sure what this says about your document, which is so far from
being in the form of the eventual language standard.  It is very
difficult to know whether we are voting on chapters 1 and 2 of the
document, on appendix A of the document, or on the abbreviated "cleanup
issues" in your straw poll.  If we're not voting on Appendix A there
is little advantage in spending time making it self-consistent.

Some observers may be wondering why I want implementation-defined
attributes to be discussed in the standard, instead of merely being
defined by the implementations.  The issue is to make it possible to
write programs that are both conforming and portable among
implementations with varying implementation-defined attributes, without
the programmer first having to study and compare the documentation of
all the implementations.  In other words, the Common Lisp language
standard should define the framework for implementation-defined
character attributes, and the individual implementations should just
fill in that framework.  If the language didn't mention the possible
existence of implementation-defined character attributes, it would
be too easy to write a program that at first seemed conforming, but
in fact would not behave as desired on an implementation with
character attributes.

∂03-Mar-89  1006	X3J13-mailer 	Issue: ERROR-TERMINOLOGY  
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 3 Mar 89  10:06:46 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA03990g; Fri, 3 Mar 89 10:00:10 PST
Received: by challenger id AA20493g; Fri, 3 Mar 89 09:55:26 PST
Date: Fri, 3 Mar 89 09:55:26 PST
From: Richard P. Gabriel <rpg@lucid.com>
Message-Id: <8903031755.AA20493@challenger>
To: x3j13@sail.stanford.edu
Subject: Issue: ERROR-TERMINOLOGY


I looked at the error terminology section as if I were the editor of
the specification, and I made some further changes. I had made an
earlier pass over the material that was intended to tighten it up, but
one can almost always continue to improve things. I showed this draft
to Moon and he said ``I am entirely happy with your proposed rewording
of the error terminology.''

The remainder of this message contains the proposed rewording:


Issue:        ERROR-TERMINOLOGY
References:   Chapter 5, Section 5.1, Working draft of the standard
	      CLOS Chapter 1
	      CLtL Chapter 1, Section 1.2.4
              Condition System, Version 18
Category:     Clarification
Edit history: 27-DEC-88, Version 1 by Chapman
              31-JAN-89, Version 2 by Chapman
              6-FEB-89, Version 3 by Chapman, RPG and Barmar comments included
              8-FEB-89, Version 4 by Chapman, added more to Current Practice
              21-FEB-89, Version 5 by Chapman, added van Roggen, RPG comments
              3-MAR-89, Version 6 by Gabriel, rewrite prompted by Moon
 
Problem Description:
In CLtL, CLOS and the Condition System, similar but slightly
different language is used to describe
non-normal actions by CL operators. The X3J13 committee needs to
agree on a standard set of terms and their meanings.
 
Proposal (ERROR-TERMINOLOGY:STANDARD TERMS)

TERM			MEANING
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
CONFORMING CODE (*)	Code that adheres to the following requirements:
			(1) Conforming code shall not use any constructions 
			that are prohibited by the standard.
			(2) Conforming code shall not depend on extensions 
			included in an implementation.

SAFE CODE (*)		Code processed with the SAFETY optimization at its
			highest setting. SAFETY is a lexical property of code.

UNSAFE CODE  (*) 	Code processed with lower safety levels.
		        Note: Unsafe code is not necesarily code that does
			not do error checking:  Implementations are
			permitted to treat all code as safe code all the time.

IS SIGNALLED   		An error is signalled in both safe and unsafe code. 
			Conforming code may rely on the fact that the error 
			will be signalled in both safe and unsafe code.
     			Every implementation is required to detect the error
			in both safe and unsafe code. For example, "an error 
			is signalled if UNEXPORT is given a symbol not 
			accessible in the current package."

SHOULD BE SIGNALLED 	An error will be signalled in safe code, and an error
		        might be signalled in unsafe code.
			Every implementation is required to detect the error 
		        at least in safe code. When the error is not 
                        signalled, the "consequences are undefined" (see
			below).  For example, "an error should be signalled
			if ENDP is given a non-list argument."

CONSEQUENCES ARE UNSPECIFIED The consequences are unpredictable but harmless.
			Implementations are permitted to specify the 
			consequences of this situation. No conforming code may 
			depend on the results or effects of this situation, 
			and all conforming code is required to treat the 
			results and effects of this situation as unpredictable 
			but harmless. For example, ``the consequences of the 
			garbage collector when invoked are unspecified.''

CONSEQUENCES ARE UNDEFINED The consequences are unpredictable. The
			consequences may range from harmless to fatal. No
			conforming code can depend on the results or
			effects. Conforming code must treat the results and
			effects as unpredictable.  In places where the
			words "must", "must not" or "may not" are used,
			then "the consequences are undefined" if the stated
			requirement is not met, and no specific consequence
			is explicitly stated.  For example: "Once a name
			has been declared by DEFCONSTANT to be constant,
			any further assignment or binding of that special
			variable has undefined consequences."

RETURN VALUES ARE UNSPECIFIED Only the number and nature of the return values 
			of a construct are not well specified but any 
			side-effect and transfer-of-control behavior is well 
			specified. For example, if the return values of some 
			function F are unspecified, then an expression such as 
			(length (list (F))) is still well-specified because it 
			does not rely on any particular aspect of the value or 
			values returned by F.

IMPLEMENTATIONS MAY BE EXTENDED An implementation is free to treat the
			situation in ANY ONE of the following ways: (1)
			When the situation occurs, an error is signalled at
			least in safe code, OR (2) When the situation
			occurs, the "consequences are undefined", OR (3)
			When the situation occurs, the consequences are
			defined.  Also, no conforming code can depend on
			the results or effects of this situation, and all
			conforming code must treat the results and effects
			of the situation as undefined.  For example,
			"implementations may be extended to define other
			type specifiers to have a corresponding class."

FREE TO EXTEND THE SYNTAX Implementations are permitted to define unambiguous 
			extensions to the syntax of the construct being 
			described. No conforming code can depend on this 
			extension. All conforming code is required to treat 
			the syntax as meaningless. The standard may disallow 
			certain extensions while allowing others. For example, 
			"no implementation is free to extend the syntax of 
			DEFCLASS."

WARNING IS ISSUED	A warning is issued, as described in WARN, in both
			safe and unsafe code and when the situation is
			detected by the compiler. Conforming code may rely
			on the fact that a warning will be issued in both
			safe and unsafe code and when the situation is
			detected by the compiler.  Every implementation is
			required to detect this situation in both safe and
			unsafe code and when the situation is detected by
			the compiler. The presence of a warning will in no
			way alter the value returned by the form which
			caused the situation to occur. For example, "a
			warning is issued by the compiler if a declaration
			specifier is not one of those defined in Chapter 9
			of CLtL and has not been declared in a DECLARATION
			declaration."

WARNING SHOULD BE ISSUED A warning may be issued. Conforming code may not
			rely on the fact that a warning will be issued. If
			the situation is detected by the compiler, a
			warning may or may not be issued, depending on the
			implementation.  The presence of a warning will in
			no way alter the value returned by the form which
			caused the situation to occur. For example, "a
			warning should be issued by a compiler if a
			variable declared to be ignored is referenced
			or is also declared special, or if a variable is
			lexical, never referenced, and not declared to be
			ignored."


(*) means this term is used to define other terms in this proposal,
not explicitly used in the standard.
 

∂03-Mar-89  1130	X3J13-mailer 	Re: Section 1.7 
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 3 Mar 89  11:30:17 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
	id AA13011; Fri, 3 Mar 89 11:28:34 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
	id AA12864; Fri, 3 Mar 89 11:24:49 PST
Received: by clam.sun.com (4.0/SMI-4.0)
	id AA26139; Fri, 3 Mar 89 11:27:58 PST
Date: Fri, 3 Mar 89 11:27:58 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8903031927.AA26139@clam.sun.com>
To: barmar@Think.COM, pierson@mist.encore.com
Subject: Re: Section 1.7
Cc: chapman%aitg.DEC@decwrl.dec.com@Multimax.encore.com,
        skona%csilvax@hub.ucsb.edu@multimax.encore.com,
        x3j13@sail.stanford.edu

I agree with Barry.  Packages not named in the standard belong
to software developers.  Otherwise every name defined by anyone
becomes an extension to Common Lisp, and I don't think we want
to define "extension" that way.

∂03-Mar-89  1202	X3J13-mailer 	Common Lisp
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 3 Mar 89  12:02:33 PST
Received: from fafnir.think.com by Think.COM; Fri, 3 Mar 89 14:56:49 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Fri, 3 Mar 89 14:58:31 EST
Received: by verdi.think.com; Fri, 3 Mar 89 14:55:18 EST
Date: Fri, 3 Mar 89 14:55:18 EST
From: Guy Steele <gls@Think.COM>
Message-Id: <8903031955.AA21691@verdi.think.com>
To: moore@cli.com
Cc: x3j13@sail.stanford.edu
Cc: Steele@Think.COM
In-Reply-To: J Strother Moore's message of Fri, 3 Mar 89 10:44:34 CST <8903031644.AA08035@client13.CLI.COM>
Subject: Common Lisp

   Date: Fri, 3 Mar 89 10:44:34 CST
   From: J Strother Moore <moore@cli.com>

   I just wanted to let you know that I love Common Lisp.
   I have used it a lot this past year extending Boyer's and
   my theorem prover and the more I've used it the more I
   like it.  You guys really did a great job.

   J

Thank you very much for the compliment.  ANSI committee X3J13
is working to clean up the rough spots and fill in the gaps;
I hope you like the revision as much as the current definition.
And of course lots of credit must go to the implementors.

This mail made my day.

--Guy Steele

∂03-Mar-89  1221	X3J13-mailer 	KMP's personal comments on 22-Feb-89 Character Proposal 
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 3 Mar 89  12:21:23 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 550353; Fri 3-Mar-89 15:17:40 EST
Date: Fri, 3 Mar 89 15:17 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: KMP's personal comments on 22-Feb-89 Character Proposal
To: Baggins@IBM.COM
cc: X3J13@SAIL.Stanford.EDU
References: <19890303165649.4.KMP@BOBOLINK.SCRC.Symbolics.COM>
Message-ID: <19890303201737.3.KMP@BOBOLINK.SCRC.Symbolics.COM>

Please find below my personal comments on the hardcopy character
proposals of 22-Feb-89 which I received from you by US Mail.
This is not the Symbolics official position. Moon will send that
at a later date.

Note that this will be my only mailing to this large list on this
issue prior to the meeting.  If I have anything further to say, I
will bring it up on CL-Characters or some smaller list. I expect,
however, that my attention will be focused on other issues.

By the way, you still have my old address (11 Cambridge Center).
The correct new address for me, Moon, and Symbolics R&D is:
 8 New England Executive Park, East
 Cambridge, MA 01803-5007

----- Comments on the Isolated Proposals (hardcopy of 22-Feb-89) -----

Presentational Comments

 - This doesn't follow the normal proposal format being used by
   other groups. As a consequence...

    - there are no examples to make certain sticky points clearer
    - there is no impact analysis
    - there is no rationale for some of the questionable changes

   I think it is unreasonable to expect people to just infer this
   kind of thing. Reasoning about these things takes a lot of time.
   Writing down your thoughts once you've reasoned about something
   takes much less time than asking someone to repeat your entire
   process in order to decide if they approve.

   Also, there is precedent for making decisions in language design
   that later are suggested to be mistakes.  Often it is hard to
   distinguish `changing goals' from `poor communication' from
   `oversight' from `typo.'  Our normal proposal format is designed
   to avoid some of these symptoms by making explicit some things
   that would not be explicit in the final document, and by adding
   redundancy that helps catch typos, miscommunication, etc.

 - The proposal descriptions are far too brief.  They are prone to
   misinterpretation. Worse, an `expansion' does not occur elsewhere.
   Often to disambiguate you have to do a lot of digging around and
   assembling things from pieces here and there.

   At the very least, there should be index information from these
   short punchy phrases to something less ambiguous. Better still 
   would be to really spell out the details in the proposal so that
   they can be examined in the abstract.
 
   Breaking this big proposal up into little ones should have 
   accomplished two things: it should have allowed us to understand
   the parts of the proposal in isolation, and it should have allowed
   independent voting. I think it currently allows neither, because
   you can't understand the individual proposals without understanding
   the whole and if you vote No on any particular part, you aren't left
   with a document that Kathy can usefully work with.

Technical Comments

 - Regarding defining that STRING-CHAR must be either BASE-CHAR or
   CHARACTER -- This seems unmotivated and I am suspicious of it.
   It seems, somehow, unnecessarily restrictive.

 - I don't mind if INT-CHAR is removed, but I don't think CHAR-INT
   should be removed. It may be useful in some hashing applications.

 - Regarding the problem description in CHARACTER-TYPE-RESTRICTIVE,
   I don't think that I believe that CHARACTER doesn't allow both fat
   and thin characters. Is this claim motivated somewhere.

 - The proposal CHARACTER-TYPE-RESTRICTIVE suggests replacing
   STANDARD-CHAR by (CHARACTER :STANDARD), but since STANDARD-CHAR
   is not really going away, this wording is misleading.

 - Proposals STRING-TYPE-RESTRICTIVE and SIMPLE-STRING-TYPE-RESTRICTIVE
   refer to making STRING and SIMPLE-STRING (respectively) union types.
   The details of this are never spelled out. The consequences are not,
   I think, appropriately analyzed. I would like to better understand the 
   relationship between this and the new array TYPEP situation to make
   sure there are no bad interactions.

 - I do not understand from the description of
   SIMPLE-STRING-TYPE-ABBREVIATIONS why adding SIMPLE-BASE-STRING
   and SIMPLE-GENERAL-STRING is an answer to the problem that new types
   are awkward to name.

Aesthetic Comments

 - I think the terms `coded character format' and `coded character set'
   are ok for a concept description, but inappropriate for a language spec.
   They are too long for convenient lunch table discussion, note taking,
   etc. If you want something to be part of a language that people use in
   a serious way, you have to either truncate the terms to manageable 
   size or expect people to do it for you. If you do it, at least that
   visitors from other companies will be able to participate in  lunch
   table discussions. If you let your users do it, there will be lots of
   gratuitous variation. The impact of this is that...

    - In FILE-EXTERNAL-REPRESENTATION, :EXTERNAL-CODED-CHARACTER-FORMAT
      is far too long. In any situation, such as with OPEN, where the
      space of keywords is not user-extensible, the need for 
      extraordinarily long names is very low because short names can
      adequately disambiguate. I see no reason why some much shorter
      keyword cannot be devised. (Just for your reference, even 
      :IF-DOES-NOT-EXIST tries my patience.)
   
      I suggest :EXTERNAL-ENCODING as a straw man, but all I really care
      about is that it be a minimal number of words, and I don't think
      the proposed choice is short enough.
   
    - In STRING-BINARY-WIDTH, I think the name EXTERNAL-CODED-STRING-LENGTH
      is again too long. It's not like people will ever add symbols to
      the LISP package, so it's not like a shorter name would be ambiguous.
      I suggest STRING-ENCODED-LENGTH (to match my :EXTERNAL-ENCODING above).
   
    - In CHAR-CODE-NON-PORTABLE, I very strongly dislike abbreviations except
      in extraordinary circumstances like `char' where the abbreviation is
      nearly ripe for adoption as an English word due to its extremely wide,
      or where the word is used so often that spelling it out would be too
      awful.
   
      However, if you spell it out, I'll complain that it is too long a term.
   
      I propose you call the thing CHAR-ENCODING.

 - In CHARACTER-IDENTIFICATION-NONPORTABLE, I don't think you've necessarily
   solved anything if you say that (a) all characters must come from some
   registry and (b) all registries must be dicated by an ISO group that doesn't
   exist. It necessarily follows that there can be no correct implementation
   until that working group finishes. What are people to do in the interim?

   It either needs to be spelled out, or it needs to be explained why what they
   do doesn't matter. [And, indeed, if it doesn't matter, then it's going to be
   hard to make the case that a lot of the existing rules are really necessary.]

Typos

 - In CHARACTER-TYPE-RESTRICTIVE, defining BASE-CHARACTER as a subtype
   of STRING seems like an extraordinarily bad idea. :-)

 - In STRING-BINARY-WIDTH, presumably the function name does not want
   to be in the KEYWORD package.

----- Comments on the Concept Part (hardcopy of 22-Feb-89) -----

Presentational Comments

 - The proposal uses the term "removed" a lot but that sometimes seems to
   mean "gets totally rid of", sometimes means "deprecates", sometimes 
   means "adds something that's really better". Maybe I'm just misreading,
   but it would be helpful in terms of being a proposal that people have to
   vote on, to clearly define these terms.

 - I am actually offended by the use of these tags like ISO8859/2-1987
   with no exposition.  This gives a `snobby' look to the paper and amounts
   to jargon because it is not intelligible by people who are on in on
   ISO affairs. I feel forced to write to ISO to get these documents just
   to know what you're talking about.  I have no sense for whether you are
   talking about something I'm familiar with under another name, or
   something totally irrelevant to me. I made annotations all over the
   document about this. It was really starting to bug me.

 - p9, last two paragraphs before 2.3 should be a single paragraph.

 - I found it hard to read about REGION-SPECIALIZED-STRING, GENERAL-STRING,
   etc. and then to think that you weren't in fact proposing it. Someone
   skimming would probably miss the word `hypothetical' ... Especially since
   my vague recollection is that this stuff was really in a previous proposal,
   I think this stuff either be much more clearly set off as an example.

Technical Comments

 - From a human interface standpoint, I think it would be desirable for 
   character repertoires to have more than one possible name.  My guess
   is -- though I have no way of proving it since no hint is given about
   what names these things refer to -- that these things have more common
   nicknames that would be more programmer-friendly if allowed. Names made
   up of mostly digits are not appealing to me.

 - If people can add non-stanard registries, there is a potential for
   confusion. If I add a private registry named FOO and then at a later
   time ISO votes in a registry named FOO, mine will suddenly appear to
   be the official one. If there a way to tell official ones from unofficial
   ones, that might avoid some problems down the road. Alternatively, if
   a portion of the registry namespace were allocated for ISO (or, 
   conversely, reserved for private use), that would solve the problem.

 - The fact that character labels must be uniquely named using only
   standard-char-p characters strikes me as having funny bootstrap
   implications. I don't know what if anything to do about that, but I
   thought I'd mention it.

 - The issue of character labels also makes me wonder about uses of 
   special chars like colon, backslash, semicolon, dollarsign which often
   have special meaning to Lisp and other languages. Further, the use
   potential to use underscore and hyphen seems like a bad idea, too,
   because some systems prefer underscore to hyphen -- and vice versa.
   Personally, I think we ought to say that character labels have to be
   made of A to Z, a to z, and 0 to 9 (with preference for alphabetics
   over numerics -- i.e., they should try to be actual words).

 - Also, who will assign character labels? Will they not be standard
   across implementations? This is a place where examples of sample uses
   would help a lot.

 - I couldn't make sense of the cryptic phrase `Reader Canonicalization'
   in a bullet item at bottom of chap 2, page 8.  I think this should
   be elaborated.

 - I've wrestled with this business of (and character (not base-character))
   a lot and come to the conclusion that you should give this a name
   in the language itself. e.g., you should deftype the name
   extended-character.  The reasons are these:

    - so it can be used in discussions, bug reports, etc.

    - so that there is a term that could be common between lisp and some
      other language -- where the other language was non-lispy and a lisp
      AND expression would not be welcome.

 - When the external encoding is not reliably using a single-byte format,
   you need to specify the consequences for the functions FILE-POSITION
   and FILE-LENGTH.

 - Is $ really what is replaced by the British pound sign on British
   displays? I had always thought that # was what was replaced. My point,
   though, is that there may be more than one axis on which to view 
   `equivalent functionality.'

   I don't think I'm disagreeing with you on the details here, but I am
   saying that I don't think it's as pretty a picture as you paint it,
   and that (like the `pathnames' section in CLtL) you risk making people
   think they're getting a more comfortable solution than they're really
   getting.

   I think the real point here should be that this is a thing which
   gratuitously varies in the marketplace and in the world, that we don't
   have a prayer of standardizing it, and we're leaving it up to vendors
   to do the best they can.

   I have a couple of specific questions, though:

    - What if a program that on American terminals types out:
       That will cost $4.00
      types out
       That will cost L4.00
      on a british screen. I'm not so sure I'm happy with that.

    - What about _ vs -. Some computer systems seem to take languages
      that are defined to distinguish case (and be all uppercase) and
      invert the case (make it all lowercase), often flipping hyphen
      and underscore, and single and doublequote in the process. Are
      these valid transformations?

 - top of p13, you say that the COERCE function is extended to allow
   for coercion from base string to extended string. Be explicit about
   how this is done.

 - Regarding footnote 18 on p13, my personal feeling is that either all
   conventions should be itemized or none should.  If none are, you can
   pick obviously hypothetical names. However, I think that to mention
   one or two encodings and not others amounts at best to advertising
   and at worst can either pin an implementation unnecessarily (by having
   an external document such as CLtL or the ANSI CL spec define something
   which might want to vary over time) or can cause a market bias toward
   implementations which have their convention mentioned over implementations
   which do not have their conventions mentioned.

 - The whole issue of non-graphic characters is almost totally omitted
   from the discussion. I think more should have been said. A parenthetical
   remark about #\Newline at top of p14 of chap 2 is about all there seemed
   to be.

 - I think the reason that EXTERNAL-CODED-STRING-LENGTH does not address
   the problem of screen width in proportional fonts should be addressed.
   Is an implication also that Huffman coding (is that how you spell it)
   in stream output is also not addressed (or possibly illegal) because
   it is context sensitive?

Typos

 - You've put some function names in italic where you meant code-font.
   e.g., in Section 2.1

-----

Due to time constraints, I only skimmed the editorial modifications to
CLtL in trying to get answers to specific questions I ran into in the
other parts. The absence of remarks about those changes shouldn't
necessarily be construed at this time as approval on my part.

∂03-Mar-89  1427	X3J13-mailer 	Re:  Issue: ERROR-TERMINOLOGY  
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 3 Mar 89  14:27:24 PST
Received: from snail.Sun.COM by Sun.COM (4.1/SMI-4.0)
	id AA19379; Fri, 3 Mar 89 14:27:47 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
	id AA21544; Fri, 3 Mar 89 14:23:46 PST
Received: by clam.sun.com (4.0/SMI-4.0)
	id AA26314; Fri, 3 Mar 89 14:27:06 PST
Date: Fri, 3 Mar 89 14:27:06 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8903032227.AA26314@clam.sun.com>
To: rpg@lucid.com, x3j13@sail.stanford.edu
Subject: Re:  Issue: ERROR-TERMINOLOGY

The terminology "CONSEQUENCES ARE UNSPECIFIED" is still a
trap in my opinion.  The example, ``the consequences of the 
garbage collector when invoked are unspecified'', is not
as appropriate as it might be, because there is no explicit
way to invoke the garbage collector in Common Lisp and the
example is not taken from the specification of the language
as far as I know.

But, what the heck, let's look at this example.  Are the
results and effects of this situation "unpredictable but
harmless"?  Not in my book.  Running the garbage collector
is supposed to have (essentially) *no* visible effects.
It can't change the value of any variable or data structure
in any observable way.  It can issue messages, I guess, and
change the report from "ROOM", but that is likely to change
with every call anyway.

Let's pick a few actual examples where the language definition is
proposed to say "consequences are unspecified".  (Go ahead, I challenge
you.)  I think we will find that the description will have to be more
specific than that.  It can make sense to say that "effect X may or may
not occur".  It can make sense to say that "data structure Y may be
modified arbitrarily".  If we can define a set of effects that we
consider harmless, and change "unpredictable but harmless" to just
"harmless", or some such, that could also make sense, but not the current
language.

∂03-Mar-89  1539	X3J13-mailer 	What is a FUNCTION?  
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 3 Mar 89  15:39:21 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA07284; Fri, 3 Mar 89 16:37:18 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA04478; Fri, 3 Mar 89 16:37:16 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903032337.AA04478@defun.utah.edu>
Date: Fri, 3 Mar 89 16:37:14 MST
Subject: What is a FUNCTION?
To: x3j13@sail.stanford.edu

From section 2.2 of the working draft:

  A FUNCTION may be supplied as an argument without error to FUNCALL or
  APPLY, and is to be executed as code when arguments are supplied.  The
  functional computation produces one or more values, produces no
  values, or takes a non-local exit.

Is this *really* the best definition of what a FUNCTION is that we can
come up with?  I've talked to some other people here and while we are
all having a remarkably hard time coming up with some specific words,
we are all agreed that this definition really misses the boat.
Surprisingly, none of the Lisp texts I have handy have much discussion
on what a function is, and the R**3 Scheme report says almost nothing
about what a procedure object is either.  I really had no idea that
there was such a gaping hole in our understanding of such an
apparently fundamental concept....

To me, it seems like the definition of the FUNCTION type ought to
incorporate at least the following four notions:

- encapsulation of process as object

- capture of lexical environment 

- generalization via parameters

- evaluation of body delayed until funcall

Also I would expect to see a statement that FUNCTION objects are
created by the evaluation of a (FUNCTION (LAMBDA ...)) form.

Would anybody like to take a stab at putting together a better
definition?

-Sandra


-------

∂03-Mar-89  1548	X3J13-mailer 	Error Terminology    
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 3 Mar 89  15:48:06 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA00688g; Fri, 3 Mar 89 15:41:25 PST
Received: by challenger id AA21289g; Fri, 3 Mar 89 15:36:54 PST
Date: Fri, 3 Mar 89 15:36:54 PST
From: Richard P. Gabriel <rpg@lucid.com>
Message-Id: <8903032336.AA21289@challenger>
To: x3j13@sail.stanford.edu
Subject: Error Terminology


Ok Cris, here is the example. It is from CLOS chapter 1.
The description is of the system-supplied method for
SHARED-INITIALIZE. The second argument specifies a list of
slots that will be dealt with in certain cases.

``There is a system-supplied primary method for {\bf
shared-initialize} whose first parameter specializer is the class {\bf
standard-object}.  This method behaves as follows on each slot,
whether shared or local:

...

\item{\bull} Any slots indicated by the second argument that are still
unbound at this point are initialized according to their {\bf
:initform} forms.  For any such slot that has an {\bf :initform} form,
that form is evaluated in the lexical environment of its defining {\bf
defclass} form and the result is stored into the slot.  For example,
if a {\bf :before} method stores a value in the slot, the {\bf
:initform} form will not be used to supply a value for the slot.  If
the second argument specifies a name that does not correspond to any
slots accessible in the instance, the results are unspecified.''

Now, should this say that if the second argument specifies a name that
does not correspond to an accessible slot that it is ignored? Well,
that is what it does in some sense, but there may be processing that
goes on to discover the fact that it should be ignored, so supplying
exactly exactly one slot that appears nowhere in the hierarchy might
take an arbitrary amount of time to discover. For example, if there
are 100,000 classes, the CPL might need to be calculated, which could
take up to 40 seconds and involve CONSing 5mbytes, possibly
side-effecting each class object in certain ways. Or while the
programmer is getting coffee, the multitasking system might have
noticed inactivity and woken up the CPL calculation process, computing
the CPL for the right classes, so when the programmer returns and
causes shared-initialize to happen, this effect doesn't happen.  Or
the search for the slot might invoke other internal initialization
procedures or protocols that should be harmless. Or maybe some
programming environment structures are altered. Or maybe some other
processes are started.

Right now I don't know even what the odd effects of the CPL
computation will be in any particular Common Lisp, and the CPL
computation might be involved in the effects of shared-initialize.

I wasn't sure what Cris meant by this argument regarding the garbage
collector:

``But, what the heck, let's look at this example.  Are the
results and effects of this situation "unpredictable but
harmless"?  Not in my book.  Running the garbage collector
is supposed to have (essentially) *no* visible effects.
It can't change the value of any variable or data structure
in any observable way.  It can issue messages, I guess, and
change the report from "ROOM", but that is likely to change
with every call anyway.''

I might point out that rehashing can happen as a result of GC, and in
parallel processing extensions to Common Lisp, running processes (such
as those behind futures) could be killed.  Output in output buffers
might be shipped to their final destinations. Weak pointer arrays
could be altered. Dispatch tables for generic functions could be
recalculated, and instances whose structure had been redefined by
forward-referencing could be re-optimized, and possibly some metaobject
protocol could be triggered.

But, ignoring these, it sounds offhand like he wasn't sure what
effects GC might have or whether they would happen (``essentially'';
``I guess''), but he was certain there would be no visible effects.
Maybe he thought the results were unpredictable but harmless?

Cris suggests:

``If we can define a set of effects that we consider harmless, and
change "unpredictable but harmless" to just "harmless"....''

My point is that it is very hard to enumerate or classify all possible
effects in all possible implementations with all possible legal
extensions on all possible hardware at all future times. And it is
much easier to define terminology that captures our intent and use it.

			-rpg-

∂03-Mar-89  1632	X3J13-mailer 	Re:  Issue: ERROR-TERMINOLOGY  
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 3 Mar 89  16:32:40 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA09474; Fri, 3 Mar 89 17:30:36 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA04518; Fri, 3 Mar 89 17:30:34 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903040030.AA04518@defun.utah.edu>
Date: Fri, 3 Mar 89 17:30:32 MST
Subject: Re:  Issue: ERROR-TERMINOLOGY
To: rpg@lucid.com
Cc: x3j13@sail.stanford.edu

I've been bothered by "the consequences are unspecified" too, although
I've kept my mouth shut on the issue up until now in the hopes that
the problem would resolve itself.

First some background.  We've had problems deciding on error
terminology for some of the compiler issues because it seems like none
of the standard error terms really say what we want, which is
something to the effect of: You can't depend on being able to compile
code that does this.  In any particular implementation, the behavior
will be well-defined, but that behavior may be (for the compiler
and/or loader) to signal an error.  Conforming programs cannot rely on
any particular behavior in this situation, but simply compiling code
that does this will not cause a crash-and-burn situation. 

Saying "the consequences are undefined" doesn't seem like the right
thing, because it permits the possibility of random crash-and-burn
errors.  I am not sure if "the consequences are unspecified" is really
right either, because I'm not sure if "harmless" was intended to
include signalling an error.

So far, in situations where it is reasonable to signal an error (for
example, issue COMPILE-FILE-SYMBOL-HANDLING), I have been using
"unspecified" but explicitly saying that it is OK to signal an error.
I would feel more confortable with this if the definition of the term
"unspecified" said that signalling errors or warnings is permissible,
at least in those situations where the standard explicitly says it is. 

A further problem with "the consequences are unspecified" is that I
think the word "consequences" is too unspecific about is being left
unspecified.  :-)  We ought to be very careful about using this phrase
and instead try to state exactly which "consequences" are unspecified.

-Sandra




-------

∂03-Mar-89  1704	X3J13-mailer 	Issue: ERROR-TERMINOLOGY  
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 3 Mar 89  17:03:58 PST
Received: from pitney-bowes ([192.9.200.50]) by heavens-gate.lucid.com id AA00803g; Fri, 3 Mar 89 16:57:17 PST
Received: by pitney-bowes id AA11422g; Fri, 3 Mar 89 16:55:51 PST
Date: Fri, 3 Mar 89 16:55:51 PST
From: Jim McDonald <jlm@lucid.com>
Message-Id: <8903040055.AA11422@pitney-bowes>
To: sandra%defun@cs.utah.edu
Cc: rpg@lucid.com, x3j13@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Fri, 3 Mar 89 17:30:32 MST <8903040030.AA04518@defun.utah.edu>
Subject:  Issue: ERROR-TERMINOLOGY

Why can't we use phrases like:

  "the consequences might be fatal"
  "the consequences might signal an error"
  "the consequences won't signal an error"

For me, saying "the consequences are undefined" is a bit like saying
"slow, construction ahead" when in fact the bridge might be out. 

  jlm

∂04-Mar-89  1159	X3J13-mailer 	Error Terminology    
To:   x3j13@SAIL.Stanford.EDU    
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>


The error terminology is useful for explaining general behavior
in various situations where we do not wish to state explicitly what could
happen, but ordinary English description is not forbidden.
That is, if you want to say that something is unspecified but might
signal an error, we don't need special terminology for that since that
phrase itself is perfectly fine. (Note: ``unspecified'' allows implementations
to specify what happens, and signalling an error is a fine specification.)

In addition, if people feel that we should elaborate on the possible
consequences of some action, we should simply spell them out. The fact we
have error terminology doesn't mean that we cannot use our judgement in
particular situations.

			-rpg-

∂06-Mar-89  1133	X3J13-mailer 	Re: KMP's personal comments on 22-Feb-89 Character Proposal  
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 6 Mar 89  11:32:45 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK   via Janet with NIFTP
           id aa02296; 6 Mar 89 18:55 GMT
Date: Mon, 6 Mar 89 19:22:51 GMT
Message-Id: <19790.8903061922@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: KMP's personal comments on 22-Feb-89 Character Proposal
To: Kent M Pitman <KMP@scrc-stony-brook.arpa>, Baggins@ibm.com
In-Reply-To: Kent M Pitman's message of Fri, 3 Mar 89 15:17 EST
Cc: X3J13@sail.stanford.edu

>  - Is $ really what is replaced by the British pound sign on British
>    displays? I had always thought that # was what was replaced.

It is often the case that hash is replaced by the british pound sign.
For example, I soon learned to recognize L'(lambda ...).  Indeed,
ASCII-based systems (machines, terminals, etc) seem to do this,
though some other things (ICL 1900 series machines, say) may replace
dollar sign with pound.

-- Jeff

∂06-Mar-89  1322	X3J13-mailer 	Re: minor comments on letter ballot material  
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 6 Mar 89  13:22:47 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 551534; Mon 6-Mar-89 16:19:23 EST
Date: Mon, 6 Mar 89 16:18 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: minor comments on letter ballot material
To: Gregor.pa@Xerox.COM, chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@SAIL.STANFORD.EDU, skona%csilvax@hub.ucsb.edu
In-Reply-To: <19890302024559.5.GREGOR@SPIFF.parc.xerox.com>
Message-ID: <19890306211857.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: Wed, 1 Mar 89 18:45 PST
    From: Gregor.pa@Xerox.COM

	Date: Wed, 1 Mar 89 18:22 EST
	From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>

	Here's a suggestion from one of our CLOS implementors.  Would this
	change (adding the word "affected") require a vote?

	Page 2-9 Redefining Classes

	   Updating such an instance occurs at an implementation-dependent time,
	   but no later than the next time a slot of that instance is read or written.

	I think I'd prefer if this said:

	   Updating such an instance occurs at an implementation-dependent time,
	   but no later than the next time an affected slot of that instance is
	   read or written.

	I (Moon again) think this is a good idea.

    This change makes it impossible for people to use MAKE-INSTANCES-OBSOLETE
    to arrange for any future access to the slots of an instance to trap.
    One of the reasons we gave for not adding an instance enumeration
    mechanism was the availability of this functionality.  So, I don't think
    we should make this change.

We could say that MAKE-INSTANCES-OBSOLETE "affects" all the slots, rather
than saying that it "affects" none of the slots.  However, I'm willing to
just drop the issue.

∂06-Mar-89  1348	X3J13-mailer 	Feb. 21 Letter Ballot: editorial issues  
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 6 Mar 89  13:48:15 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 551584; Mon 6-Mar-89 16:45:08 EST
Date: Mon, 6 Mar 89 16:44 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Feb. 21 Letter Ballot: editorial issues
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
In-Reply-To: <8902211607.AA09708@decwrl.dec.com>
Message-ID: <19890306214441.8.MOON@EUPHRATES.SCRC.Symbolics.COM>

This is the official response of Symbolics to the Feb 21 1989
letter ballot on Common Lisp editorial issues.

 ________________________________________________________________________
 Issue or section name          |   Version      |  Y   |   I   |   A   |
 ------------------------------------------------------------------------
 CUT-OFF-DATES                  |      4         |  Y   |       |       |
 ------------------------------------------------------------------------
 ERROR-TERMINOLOGY              |      5         |      |   I   |       |
 ------------------------------------------------------------------------
 FONTS                          |      2         |  Y   |       |       |
 ------------------------------------------------------------------------
 TOC                            |      1         |  Y   |       |       |
 ------------------------------------------------------------------------
 Section 1.8                    |     5.8        |      |   I   |       |
 ------------------------------------------------------------------------
 Section 2.3                    |     5.8        |      |   I   |       |
 ------------------------------------------------------------------------
 Section 2.4                    |     5.8        |      |   I   |       |
 ------------------------------------------------------------------------
 Section 2.5                    |     5.8        |      |   I   |       |
 ------------------------------------------------------------------------
 Section 6.1                    |     5.8        |      |   I   |       |
 ------------------------------------------------------------------------

Accompanying comments:

ERROR-TERMINOLOGY: The version included with the ballot is inadequate
(details criticisms in comments mailed earlier from Moon and from Pitman).
The more recent draft mailed out by Gabriel is better.  We intend to
vote yes when we see a draft that is precise, self-consistent, and
doesn't contain examples that contradict the rest of the definition of
Common Lisp; we believe the most recently mailed draft is quite close to
that and would be surprised not to see an acceptable draft at the March
meeting.

The five numbered sections: We approve these in principle, but aren't
ready to cast them in concrete.  We haven't had time to review them with
the extreme care warranted for a language standard, and don't know who
else, if anyone, has reviewed them that thoroughly.  We intend to vote
yes when we know that these have been reviewed with good judgement and
attention to detail, or if informed that voting yes does not mean that
these sections will be put into the standard without permitting an
opportunity for further review and correction.

∂06-Mar-89  1355	X3J13-mailer 	minor comments on letter ballot material 
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 6 Mar 89  13:55:10 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA02303g; Mon, 6 Mar 89 13:46:42 PST
Received: by challenger id AA25811g; Mon, 6 Mar 89 13:41:55 PST
Date: Mon, 6 Mar 89 13:41:55 PST
From: Patrick Dussud <dussud@lucid.com>
Message-Id: <8903062141.AA25811@challenger>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
Cc: Gregor.pa@Xerox.COM, chapman%aitg.DEC@decwrl.dec.com,
        x3j13@SAIL.STANFORD.EDU, skona%csilvax@hub.ucsb.edu
In-Reply-To: David A. Moon's message of Mon, 6 Mar 89 16:18 EST <19890306211857.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: minor comments on letter ballot material

   Date: Mon, 6 Mar 89 16:18 EST
   From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
   Line-Fold: No


       This change makes it impossible for people to use MAKE-INSTANCES-OBSOLETE
       to arrange for any future access to the slots of an instance to trap.
       One of the reasons we gave for not adding an instance enumeration
       mechanism was the availability of this functionality.  So, I don't think
       we should make this change.

   We could say that MAKE-INSTANCES-OBSOLETE "affects" all the slots, rather
   than saying that it "affects" none of the slots.  However, I'm willing to
   just drop the issue.

I think it's hard to do. It is specified that class redefintion will call
make-instances-obsolete. So all the slots would be affected whenever a class
redefinition makes the instances obsolete. 
We could do it by changing make-instances-obsolete to take a list of slots to
mark as affected.

Patrick.

∂06-Mar-89  1453	X3J13-mailer 	Re: cs proposal comments  
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 6 Mar 89  14:53:45 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 551649; Mon 6-Mar-89 17:51:21 EST
Date: Mon, 6 Mar 89 17:51 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: cs proposal comments
To: David N Gray <Gray@DSG.csc.ti.com>, Thom Linden <baggins@IBM.com>
cc: x3j13@sail.stanford.edu
In-Reply-To: <2813859524-5211323@Kelvin>
Message-ID: <19890306225107.0.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Thu, 2 Mar 89  13:38:44 CST
    From: David N Gray <Gray@DSG.csc.ti.com>

    > >>   Never mind that; the real question is why do you want the standard to not
    > >>   specify the meaning of tabs and form-feeds in source files?
    > >>
    > I don't have my CLtL with me but I don't think a meaning is given
    > to the semi-standard characters (unless we consider them self defining?)

    I'm talking about page 336 of CLtL which specifies that the reader treats
    #\TAB and #\PAGE as whitespace.  Section A.22.1.1 of the February 21 document
    specifies deleting the mention of these.

I think I saw several messages complaining about this.  I think it would
actually be okay to remove the semi-standard characters, and that this would
not mean that portable programs could not be written with tabs and form-feeds.
It's already the case that when porting a program between implementations one
may have to do character set translation on the source text of the program.
When porting to an implementation that does not have tab or formfeed (which
is already legal), the character set translation must change those into
spaces, or something.

On the other hand, a nice thing about CLtL is the way it said that an
implementation doesn't have to support tabs, but if it does have tabs,
this is how they should work.  Thus the programmer can rely on having
only two tab stories to deal with: either tabs work as some amount of
whitespace, or there aren't any tabs at all.  Thus it might make sense
to retain these characters with the same semi-standard status.  I don't
see how doing that would harm the rest of the characters proposal.
Since it says somewhere that implementations are allowed to support only
a subset of a registry, it would be valid to support only a subset of
the control-characters registry (format-effectors might be a better
name).

∂06-Mar-89  1449	X3J13-mailer 	Re: cs proposal and straw vote 
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 6 Mar 89  14:49:36 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 551645; Mon 6-Mar-89 17:44:45 EST
Date: Mon, 6 Mar 89 17:44 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: cs proposal and straw vote
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>, baggins@ibm.com
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903021757.AA03241@defun.utah.edu>
Message-ID: <19890306224429.9.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Thu, 2 Mar 89 10:57:40 MST
    From: sandra%defun@cs.utah.edu (Sandra J Loosemore)

    ....
    Why do we need CHAR-CODE-LIMIT, CODE-CHAR, and CHAR-CODE anyway?
    While bits and fonts were in the standard, these were useful for
    things like creating a character with the same code but different bits
    or font attributes, but now that's out.  If we want a function to use
    for hashing characters, that's what CHAR-INT is for.  The only other
    use I can think of is supporting iteration over characters, and it
    seems like this could be extremely inefficient in implementations that
    support user-defined character sets.  (In such a case, I would imagine
    that one would make CHAR-CODE-LIMIT correspond to the limit imposed by
    the representation, perhaps the same as MOST-POSITIVE-FIXNUM, but in
    actual practice, very few of those codes would have corresponding
    characters.)  I agree with Dan that we'd be better off having a
    specialized iterator.

You left out the most obvious use, which is associating data of some
sort with characters by making an array indexed by char-code.  I agree
that this will not be practical in implementations where CHAR-CODE-LIMIT
is very large.

I didn't really understand Dan's suggestion for a specialized iterator,
since in one paragraph he said it was premature to put in character
registries, then in the next paragraph he said there should be an
iterator that takes a character registry and executes the body for
each character in that registry.

I think that the char-code stuff needs to be retained to ease the writing
of applications that are portable between implementations with different
sets of implementation-defined character attributes.  However, I would
probably not object strenuously to the removal of the char-code stuff
(I can't promise; I'd have to check with other Symbolians first) since
it could become an implementation-dependent extension.

    Should we consider extending MAKE-STRING-OUTPUT-STREAM to take an
    :ELEMENT-TYPE keyword?

That seems like a good idea.  WITH-OUTPUT-TO-STRING also.  An idea which
I slightly prefer is that WITH-OUTPUT-TO-STRING when no string argument
is provided and MAKE-STRING-OUTPUT-STREAM produce a stream that accepts
all characters and returns a string of some element-type that
accomodates all the characters that were actually output.  This reflects
Symbolics current practice.

In fact Symbolics Genera will also widen a base-string provided as a
string argument to WITH-OUTPUT-TO-STRING into a general-string if
necessary.  If we wanted to put that into the standard, that would be
great as the user would never have to worry about the element-type,
however if other implementors object I won't push it.

∂06-Mar-89  1538	X3J13-mailer 	Re: cs proposal and straw vote 
Received: from multimax.encore.com by SAIL.Stanford.EDU with TCP; 6 Mar 89  15:37:53 PST
Received: from mist.encore.COM by multimax.encore.com with SMTP (5.61/25-eef)
	id AA12950; Mon, 6 Mar 89 18:35:51 -0500
Received: from localhost by mist. (4.0/SMI-4.0)
	id AA15870; Mon, 6 Mar 89 18:33:59 EST
Message-Id: <8903062333.AA15870@mist.>
To: "David A. Moon" <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Cc: x3j13@sail.stanford.edu
Subject: Re: cs proposal and straw vote 
In-Reply-To: Your message of Mon, 06 Mar 89 17:44:00 -0500.
             <19890306224429.9.MOON@EUPHRATES.SCRC.Symbolics.COM> 
Date: Mon, 06 Mar 89 18:33:55 EST
From: Dan L. Pierson <pierson@mist.encore.com>

    Date: Mon, 6 Mar 89 17:44 EST
    From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>

    I didn't really understand Dan's suggestion for a specialized iterator,
    since in one paragraph he said it was premature to put in character
    registries, then in the next paragraph he said there should be an
    iterator that takes a character registry and executes the body for
    each character in that registry.

It's actually very simple.  I have doubts about putting registries in
at all, but IF we do decide to put them in there should be a way to
iterate over them.

∂06-Mar-89  1627	X3J13-mailer 	cs proposal straw vote    
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 6 Mar 89  16:27:30 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 551767; Mon 6-Mar-89 19:23:38 EST
Date: Mon, 6 Mar 89 19:23 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: cs proposal straw vote
To: Thom Linden <baggins@IBM.com>
cc: Common Lisp mailing <x3j13@sail.stanford.edu>
In-Reply-To: <890222.120815.baggins@almvma>
Message-ID: <19890307002320.4.MOON@EUPHRATES.SCRC.Symbolics.COM>

This is the official response from Symbolics to the 22 Feb 89
straw vote on the characters proposal.

The format in which this was presented makes it very difficult to
know what we're voting on.  Fortunately, it's only a straw poll.
However, you need to be aware that we had to guess what exactly
we're voting on, and so the results of the straw poll might not
be too meaningful, if different participants made different guesses.
I would strongly suggest casting this material into a precise
and unambiguous form before the binding vote occurs.  That could
save a great deal of discussion time and minimize the possibility
of perfectly good language features being voted down simply because
of the way they were presented.  It's especially important not to
retain the current format, where things are discussed in three places
(the body of the proposal, the appendix, and the ballot) and the
three places contradict each other in significant ways.

Issue: CHAR-FONT-UNUSED-CHAR-BITS-NONPORTABLE

Yes.  We will want to check the p.29 rules for implementation-dependent
character attributes carefully.

Issue: CHAR-INT-ONLY-USEFUL-WHEN-ATTRIBUTES-SUPPORTED

No.  CHAR-INT is needed for hashing.  CHAR-INT should be retained, but
INT-CHAR and its shadow in the COERCE function should be removed.
This issue is unrelated to the apparent primary goal of the proposal.

Issue: CHARACTER-TYPE-RESTRICTIVEC
          Define BASE-CHARACTER as a subtype of STRING.

No.  Yes to BASE-CHARACTER as a subtype of CHARACTER.

          Standard characters are a subset of the base
             characters.
Yes.

          STANDARD-CHAR type is replaced by (CHARACTER :STANDARD)

No.  Keep STANDARD-CHAR.  A change here is unnecessary for the rest of
the proposal.  Adding (CHARACTER :STANDARD) would be okay, not adding it
would also be okay.

          Remove the semi-standard characters.

No.  A change here is unnecessary for the rest of the proposal.

Issue: STRING-TYPE-RESTRICTIVE
          Define STRING as a union type
Yes

          STRING used as a type specifier for object creation
             means (VECTOR CHARACTER)
Yes

          All string functions operate as specified on any
             string object except it is an error to insert
             an extended character into a base string.

Yes.  This is already required by the requirement on storing
into arrays in general.

          Extend the COERCE function to allow coercion from
            base string to extended string.

No, this feature is already present in CLtL, since any sequence
type can be coerced to any other sequence type.

Issue: STRING-TYPE-ABBREVIATIONS

Yes.

Issue: SIMPLE-STRING-TYPE-RESTRICTIVE
          Define SIMPLE-STRING as a union type

Abstain.  We want to understand the consequences of this better,
vis a vis the alternative of defining SIMPLE-STRING as a
particular type, either (AND SIMPLE-ARRAY GENERAL-STRING)
or (AND SIMPLE-ARRAY BASE-STRING).

          Define SIMPLE-STRING as a type specifier for object
             creation means (SIMPLE-ARRAY CHARACTER (size))

Depends on the outcome of the previous.

Issue: SIMPLE-STRING-TYPE-ABBREVIATIONS
          Add SIMPLE-BASE-STRING
          Add SIMPLE-GENERAL-STRING

Depends on the outcome of the previous.  This is getting to
be too many names.

Issue: FILE-EXTERNAL-REPRESENTATION
          Add :EXTERNAL-CODED-CHARACTER-FORMAT keyword to OPEN

Approved in principle, but the name is too long.

Issue: CHAR-CODE-NON-PORTABLE
          Add CHAR-CCS-VALUE function

Approved in principle, but the name is too long, uses an unmotivated
abbreviation "ccs", and is not consistent with the name of the OPEN
keyword.  Although they don't do exactly the same thing (the OPEN
keyword can specify multiple coded character sets and a protocol
for switching among them), they are related enough that the names
should express their relation.

This issue is unrelated to the apparent primary goal of the proposal.

For both of the above, the main naming problem seems to be to keep
clear the distinction between these and CHAR-CODE.  How about
CHAR-EXTERNAL-CODE for the function name and :EXTERNAL-CODE for
the OPEN keyword?  These aren't the best names in the world, but
they are an improvement, maybe someone else can think of something
better.

Also this seems to be an incomplete set of facilities.  Conversion
of characters to external codes is provided, but not the inverse.
Conversion between internal and external encodings is bundled with
stream I/O, but not available on its own; there could be functions
that convert a string to/from a vector of integers under a specified
"external-coded-character-format".

Issue: STRING-BINARY-WIDTH
          Add EXTERNAL-CODED-STRING-LENGTH function

No.  The meaning of what this returns is too implementation-dependent
and the need for this has not been shown.  If this is retained, the name
should be consistent with the names of the preceding two facilities.
This issue is unrelated to the apparent primary goal of the proposal.

Issue: CHARACTER-IDENTIFICATION-NONPORTABLE
           Introduce the concept of Registries

We incline towards yes, except that the relation to ISO work has not
been made clear.  In particular, how can registries be used before the
putative ISO committee is formed and completes its work?

           Standardize on #\registry:id

Yes, assuming we guessed correctly what this was supposed to mean.

           add all-implemented-registries
           Add *ALL-CHARACTER-REGISTRY-NAMES* variable

Yes to one, no to the other.  The second name is better.

           Add FIND-CHAR function
           Add CHAR-LABEL function
           Add CHAR-REGISTRY-NAME function

Yes to these three.

           New syntax for CHARACTER type specifier
           New argument to CHARACTERP

No, the need for these has not been shown.  Why not
call the CHAR-REGISTRY-NAME function?

           New #\label:registry character name syntax

No, contradicts #\registry:id just above.

Is this issue unrelated to the apparent primary goal of the proposal?
That's the big question, isn't it?  A more constructive way to put the
question is, how would a program make use of character registries to
access portably characters outside of the 96 characters that all Common
Lisp implementations must have?  The proposal appears to be completely
silent on that point.  We think we know how character registries would
actually be very useful for that.  However, instead of counting on the
reader to guess the usefulness of character registries, the proposal
should contain some examples.  If the character committee can't come up
with any examples, then perhaps character registries aren't really
needed.

∂06-Mar-89  1714	X3J13-mailer 	Review schedule reminder  
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 6 Mar 89  17:13:56 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 551816; Mon 6-Mar-89 20:11:10 EST
Date: Mon, 6 Mar 89 20:10 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Review schedule reminder
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
In-Reply-To: <8902271052.AA15941@decwrl.dec.com>
Message-ID: <19890307011058.0.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: 27 Feb 89 05:31
    From: chapman%aitg.DEC@decwrl.dec.com

    Please let me know if you have any trouble accessing or reviewing this 
    information.

I am not equipped to do anything with the tex source files you've been
mailing out.  So far I have been unable to open a network connection
to hudson.dec.com to access the dvi file.

∂07-Mar-89  0254	X3J13-mailer 	clarification   
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 7 Mar 89  02:54:26 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA06496; Tue, 7 Mar 89 02:52:25 PST
Message-Id: <8903071052.AA06496@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
	for x3j13@sail.stanford.edu; id AA06496; Tue, 7 Mar 89 02:52:25 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 7 Mar 89 05:47
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: clarification

In Symbolics' vote, Moon mentioned that he wasn't willing to vote on the
sections on the letter ballot because he was afraid they would be cast
in concrete. I should have made it more clear that these sections can
be changed, via clean-up, after they have been voted on. 

I am trying to get incremental closure on the standard, just as one would
stop gratuitous changes on software being developed in a large system 
a few modules at a time. That never means that the modules originally
"fixed" will not be subject to change if the whole system doesn't work!

Please do not be afraid to spend time reviewing these sections now and
commenting if there are problems. Even if the volume of reading looks
large, imagine how large it will look in a few months when you have 
over 1000 pages to review.

Please review and vote!!!

kc

∂07-Mar-89  1334	X3J13-mailer 	hotel for march meeting   
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 7 Mar 89  13:34:03 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA03677g; Tue, 7 Mar 89 13:27:16 PST
Received: by challenger id AA28084g; Tue, 7 Mar 89 13:22:41 PST
Date: Tue, 7 Mar 89 13:22:41 PST
From: Jan Zubkoff <jlz@lucid.com>
Message-Id: <8903072122.AA28084@challenger>
To: x3j13@sail.stanford.edu
Subject: hotel for march meeting

I have reserved rooms for X3J13 but it is up to you to make your personal
reservations.
---jan---

∂07-Mar-89  1403	X3J13-mailer 	Agenda DRAFT    
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 7 Mar 89  14:03:22 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA03717g; Tue, 7 Mar 89 13:56:36 PST
Received: by challenger id AA28137g; Tue, 7 Mar 89 13:52:01 PST
Date: Tue, 7 Mar 89 13:52:01 PST
From: Jan Zubkoff <jlz@lucid.com>
Message-Id: <8903072152.AA28137@challenger>
To: x3j13@sail.stanford.edu
Subject: Agenda DRAFT


X3J13 Committee Meeting Agenda DRAFT
March 28 - 30, 1989
Fairfax, VA


 1	Call to Order, Tuesday, March 28, 9:00am 
 2	Opening Remarks and Introductions 
	 - Opening Remarks, Bob Mathis (10 minutes)
	 - Introduction of attendees
	 - Future meetings, Jan Zubkoff (5 minutes)
 3	Approval of Agenda
 4	Approval of Minutes
 5	Other Business
 6	Cleanup Subcommittee Report, Larry Masinter
 7	Coffee Break 10:30
 8	Cleanup Subcommittee Report continuation
 9	LUNCH 12:00 
10	Cleanup Subcommittee Report continuation
11	Recess, 5:00pm

12	Call to Order, Wednesday, March 29,  9:00am
13	Character Subcommittee Report, Thom Linden (4 hours)
14	Coffee Break 10:30am 
15	Character Subcommittee Report continuation
16	Lunch 12:00 
17	Character Subcommittee Report continuation
18	Compiler Subcommittee Report, Sandra Loosemore (2 hours)
19	Break 3:00 
20	Compiler Subcommittee Report continuation
21	Recess 5:00

22	Call to Order, Thursday, March 30,  9:00am
23	Editorial Subcommittee Report, Kathy Chapman (1.5 hours)
24	Coffee Break 10:30 
25	Cleanup Subcommittee  Report continuation
26	Lunch 12:00
27	Cleanup Subcommittee Report continuation
28	Break 3:00
29	Cleanup Subcommittee Report continuation
30	Adjournment 5:00pm







∂07-Mar-89  1429	X3J13-mailer 	registration list    
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 7 Mar 89  14:29:22 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA03769g; Tue, 7 Mar 89 14:22:28 PST
Received: by challenger id AA28211g; Tue, 7 Mar 89 14:17:54 PST
Date: Tue, 7 Mar 89 14:17:54 PST
From: Jan Zubkoff <jlz@lucid.com>
Message-Id: <8903072217.AA28211@challenger>
To: x3j13@sail.stanford.edu
Subject: registration list

                      X3J13 Attendee Information
                             03/07/89
 
Name                       Institute                  Paid    L1  L2  L3
David Bartley              TI                         -0-      y   y   y
Paul Beiser                HP                         -0-      y   y   y
Mary Boelk                 Johnson Controls, Inc.     -0-      y   y   y
Kathy Chapman              DEC                        -0-      -   -   -
Jeff Dalton                University of Ediburgh     -0-      y   y   y
Patrick Dussud             Lucid, Inc.                -0-      y   y   y
Dick Gabriel               Lucid, Inc.                -0-      y   y   y
David Gray                 TI                         50.00    y   y   y
Masayuki Ida               Aoyama Gakuin University   -0-      y   y
Gregor Kiczales            Xerox Corp.                -0-      y   y   y
Dieter Kolb                Siemans                    -0-      y   y   y
Tim Koschmann              Xerox                      -0-      y   y   y
Aaron Larson               Honeywell S&RC             -0-      y   y   y
Kevin Layer                Franz, Inc.                50.00    y   y   y
Thom Linden                IBM                        50.00    y   y   y
David Loeffler             MCC                        50.00    y   y   y
Sandra Loosemore           University of Utah         -0-      y   y   y
Barry Margolin             Thinking Machines          50.00    y   y   y
Larry Masinter             Xerox Corp.                -0-      y   y   y
Robert Mathis              CONTEL                     -0-      y   y   y
David Moon                 Symbolics                  -0-      y   y   y
Cris Perdue                Sun Microsystems           -0-      y   y   y
Dan Pierson                Encore Computer            -0-      y   y   y
Kent Pitman                Symbolics                  -0-      y   y   y
Guy Steele                 Thinking Machines          -0-      y   y   y
Paul Tucker                IBM                        -0-      y   y   y
Walter van Roggen          DEC                        -0-      y   y   y
JonL White                 Lucid, Inc.                -0-      y   y   y
Jan Zubkoff                Lucid, Inc.                -0-      y   y   y

∂08-Mar-89  0523	X3J13-mailer 	Issue: PLUS-ABNORMAL 
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 8 Mar 89  05:22:59 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA27292; Wed, 8 Mar 89 05:21:03 PST
Message-Id: <8903081321.AA27292@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
	for x3j13@sail.stanford.edu; id AA27292; Wed, 8 Mar 89 05:21:03 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 8 Mar 89 08:20
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: Issue: PLUS-ABNORMAL

Sorry about that. Disregard that last issue. It should have been sent
to cl-cleanup.

∂08-Mar-89  0520	X3J13-mailer 	Issue: PLUS-ABNORMAL 
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 8 Mar 89  05:20:36 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA27193; Wed, 8 Mar 89 05:18:36 PST
Message-Id: <8903081318.AA27193@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
	for x3j13@sail.stanford.edu; id AA27193; Wed, 8 Mar 89 05:18:36 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 8 Mar 89 08:18
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: Issue: PLUS-ABNORMAL

Issue:        PLUS-ABNORMAL
References:   +, ++, +++ (p. 325)
Category:     CLARIFICATION
Edit history: 1-MAR-89, Version 1 by Chapman


Problem Description:

The description of +, ++, and +++
does not mention the possibility of abnornal termination of
the evaluation of the variable {\tt +}.
Are the values associated with {\tt ++}, 
and {\tt +++} are updated?

Proposal (PLUS-ABNORMAL:UPDATE)

If the evaluation of the variable {\tt +} is aborted for some reason,
then the values associated with {\tt ++}, 
and {\tt +++} are updated.


Rationale:

This clarification is primarily to establish the contents of these
variables in all cases.

Current Practice:

VAX Lisp updates the values.

Adoption Cost:

?

Benefits:

Disambiguity.

Conversion Cost:

?
Aesthetics:

None.

Discussion:


∂08-Mar-89  1649	X3J13-mailer 	February 21 Ballot   
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 8 Mar 89  16:49:01 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA05400g; Wed, 8 Mar 89 16:42:11 PST
Received: by challenger id AA00614g; Wed, 8 Mar 89 16:37:36 PST
Date: Wed, 8 Mar 89 16:37:36 PST
From: Richard P. Gabriel <rpg@lucid.com>
Message-Id: <8903090037.AA00614@challenger>
To: x3j13@sail.stanford.edu
Subject: February 21 Ballot


Here is Lucid's vote. There are two conditional acceptances. One is
because several of us are rewriting the error terminology yet again.
The other is section 6.1 where I want to look at the notation
introduced there once more. Also, there are some minor problems with
the rest of the section, (for example, fill pointers and pathnames
should be described somewhere else.) The sections on CLOS (1.8, 2.3,
2.4, 2.5) were put together by Kathy, Linda DeMichiel, and me, so I
think they're ok from the CLOS committee's point of view.

 ________________________________________________________________________
 Issue or section name          |   Version      |  Y   |   I   |   A   |
 ------------------------------------------------------------------------
 CUT-OFF-DATES                  |      4         |  Y   |       |       |
 ------------------------------------------------------------------------
 ERROR-TERMINOLOGY              |      5         |      |   I   |       |
 ------------------------------------------------------------------------
 FONTS                          |      2         |  Y   |       |       |
 ------------------------------------------------------------------------
 TOC                            |      1         |  Y   |       |       |
 ------------------------------------------------------------------------
 Section 1.8                    |     5.8        |  Y   |       |       |
 ------------------------------------------------------------------------
 Section 2.3                    |     5.8        |  Y   |       |       |
 ------------------------------------------------------------------------
 Section 2.4                    |     5.8        |  Y   |       |       |
 ------------------------------------------------------------------------
 Section 2.5                    |     5.8        |  Y   |       |       |
 ------------------------------------------------------------------------
 Section 6.1                    |     5.8        |      |   I   |       |
 ------------------------------------------------------------------------


			-rpg-

∂08-Mar-89  1741	X3J13-mailer 	Feb. 21 Letter Ballot: editorial issues  
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 8 Mar 89  17:41:03 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 553455; Wed 8-Mar-89 20:38:11 EST
Date: Wed, 8 Mar 89 20:37 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Feb. 21 Letter Ballot: editorial issues
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
In-Reply-To: <19890306214441.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890309013751.3.MOON@EUPHRATES.SCRC.Symbolics.COM>

I'd like to change the Symbolics vote, since you told me two things
that none of us here knew before: that there will be an opportunity
for cleaning up these sections even after they are voted in now, and
that the CLOS sections had already been carefully reviewed by Gabriel
and that Gregor had said he was satisfied with them.  As a result,
we're changing our vote on sections 2.3, 2.4, and 2.5 from I to Y.
The other three I votes should remain.  For ERROR-TERMINOLOGY because
it seems to be actively changing, for section 1.8 because the section
is sketchy, and for section 6.1 because we haven't really understood
it yet.  Section 6.1 looks fundamental, do you think it's important
to get a vote on it as soon as possible?  If so, we at Symbolics could
try to concentrate our efforts there.

I'd also like to clarify the meaning of this paragraph of our reply:

  The five numbered sections: We approve these in principle, but aren't
  ready to cast them in concrete.  We haven't had time to review them with
  the extreme care warranted for a language standard, and don't know who
  else, if anyone, has reviewed them that thoroughly.

This was certainly not meant to give the impression that we were
refusing to review this stuff!  The problem is simply that except for
Pitman, who is on the editorial committee, no one here had seen any of
this before two weeks ago.  Also as it happens it is an extremely busy
time for us right now.  Two weeks would not enough time for a really
careful review even in slack times, but at the time it was impossible.

I personally plan to try to review the entire standard carefully, as
well as to browbeat several other people at Symbolics into doing careful
review of either the entire standard or selected sections for their
areas of expertise.  That will take a significant amount of time, of
course, probably several months.

∂09-Mar-89  1340	X3J13-mailer 	Issue: SUBSETTING-POSITION
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Mar 89  13:40:03 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 554074; Thu 9-Mar-89 16:37:07 EST
Date: Thu, 9 Mar 89 16:36 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: SUBSETTING-POSITION
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
In-Reply-To: <8902200927.AA06837@decwrl.dec.com>
Message-ID: <19890309213655.4.MOON@EUPHRATES.SCRC.Symbolics.COM>

I support SUBSETTING-POSITION:NONE.  I think that subsets are
a good idea, but I also think that the X3J13 process has no
chance at all of coming up with a subset that is useful to
anyone in the time available.  Therefore I think the standard
should propose no subsets, but should not contain any statement
(unlike, I think, Ada) to the effect that subsets are forbidden
or a bad idea.

∂09-Mar-89  1345	X3J13-mailer 	Issue: EXTENTIONS-POSITION
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Mar 89  13:45:26 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 554086; Thu 9-Mar-89 16:42:43 EST
Date: Thu, 9 Mar 89 16:42 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: EXTENTIONS-POSITION
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
In-Reply-To: <8902242224.AA13754@decwrl.dec.com>
Message-ID: <19890309214233.5.MOON@EUPHRATES.SCRC.Symbolics.COM>

I favor EXTENSIONS-POSITION:DOCUMENTATION.

I oppose EXTENSIONS-POSITION:DISABLE because it mandates a
particular development environment feature, but Common Lisp
has avoided saying anything about development environments
since that is an area of extreme controversy.

Gabriel's position of standing mute would be okay with me.

∂09-Mar-89  1349	X3J13-mailer 	Issue: MACRO-AS-FUNCTION  
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Mar 89  13:49:18 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 554092; Thu 9-Mar-89 16:46:30 EST
Date: Thu, 9 Mar 89 16:46 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: MACRO-AS-FUNCTION
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu
In-Reply-To: <8902242236.AA14651@decwrl.dec.com>
Message-ID: <19890309214619.6.MOON@EUPHRATES.SCRC.Symbolics.COM>

Why don't we just change PROG1 and PROG2 to functions, now that
we have clarified that functions evaluate their arguments in
left-to-right order?

∂09-Mar-89  1350	X3J13-mailer 	Issue: UNSOLICITED-MESSAGES (Version 2)  
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Mar 89  13:50:21 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 554094; Thu 9-Mar-89 16:47:35 EST
Date: Thu, 9 Mar 89 16:47 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: UNSOLICITED-MESSAGES (Version 2)
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu
In-Reply-To: <8902242237.AA14750@decwrl.dec.com>
Message-ID: <19890309214725.7.MOON@EUPHRATES.SCRC.Symbolics.COM>

UNSOLICITED-MESSAGES:NOT-TO-SYSTEM-USER-STREAMS is okay.

∂09-Mar-89  1352	X3J13-mailer 	Issue: UNSPECIFIED-DATATYPES (Version 2) 
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Mar 89  13:52:35 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 554096; Thu 9-Mar-89 16:49:52 EST
Date: Thu, 9 Mar 89 16:49 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: UNSPECIFIED-DATATYPES (Version 2)
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu
In-Reply-To: <8902242237.AA14708@decwrl.dec.com>
Message-ID: <19890309214942.8.MOON@EUPHRATES.SCRC.Symbolics.COM>

I oppose UNSPECIFIED-DATATYPES:NO-EXCEPT-AS-EXPLICITLY-ALLOWED
on the grounds that it is unnecessary and that the problem it's
attempting to address (making it possible to check conformance
by machine) is impossible to solve.

∂09-Mar-89  1357	X3J13-mailer 	Issue: EXTRA-SYNTAX (Version 4)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Mar 89  13:57:48 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 554101; Thu 9-Mar-89 16:55:10 EST
Date: Thu, 9 Mar 89 16:54 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: EXTRA-SYNTAX (Version 4)
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
In-Reply-To: <8902271015.AA14142@decwrl.dec.com>
Message-ID: <19890309215459.9.MOON@EUPHRATES.SCRC.Symbolics.COM>

I oppose EXTRA-SYNTAX:NO.  The rationale says 

  It would be very difficult for a program-analyzing-program to detect 
  such an extension. Non-portable programs could easily result.

I can't see what's hard about detecting use of additional syntax not
specified -- that seems to be the easiest to detect of any
nonconformance.  To take the canonical example of extending IF to allow
more than three subforms, surely it is very easy for a
program-analyzing-program to detect an invocation of IF with more than
three subforms and complain that the program is non-conforming.

∂09-Mar-89  1406	X3J13-mailer 	Issue: EXTRA-OPTIONAL-KEYWORD-ARGUMENTS (Version 3)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 Mar 89  14:06:06 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 554109; Thu 9-Mar-89 17:03:09 EST
Date: Thu, 9 Mar 89 17:02 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: EXTRA-OPTIONAL-KEYWORD-ARGUMENTS (Version 3)
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
In-Reply-To: <8902271016.AA14193@decwrl.dec.com>
Message-ID: <19890309220257.0.MOON@EUPHRATES.SCRC.Symbolics.COM>

I oppose both proposals.  The adoption cost is:

  Implementors will be required to determine which parts of their
  implementations are conforming and which parts aren't.  Implementors
  will have to provide a candidate list of exceptions to the editorial
  committee.

The second sentence strikes me as a lot of extra work that will just
delay closure on the standard.

The stated benefits are:

  It will be more possible to write portable programs. Also, future
  standards will be less likely to make changes that are incompatible
  with current implementations.

I don't believe in the first benefit.  This issue does not affect the
ability to write portable programs in any significant way.  It only
affects whether particular implementations are more or less useful as
development tools for checking conformance.  I believe that development
tools for checking conformance are a valuable item for which market
demand exists, but are not within the purview of X3J13.

The second benefit is true.  However there are a large number of other
ways that future standards could be incompatible with current
implementations, none of which have been ruled out.  For example, any
implementation that makes symbols accessible to the USER package other
than symbols in the LISP package risks name conflicts with future
additions to the LISP package.  It's simply a fact of life that any
extension might be incompatible with an eventual standard; pioneers can
never be sure that everyone will follow in their exact footsteps.

∂09-Mar-89  1433	X3J13-mailer 	Issue: EXTRA-SYNTAX (Version 4)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 9 Mar 89  14:33:19 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA06700g; Thu, 9 Mar 89 14:26:23 PST
Received: by challenger id AA02174g; Thu, 9 Mar 89 14:21:48 PST
Date: Thu, 9 Mar 89 14:21:48 PST
From: Richard P. Gabriel <rpg@lucid.com>
Message-Id: <8903092221.AA02174@challenger>
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: Issue: EXTRA-SYNTAX (Version 4)


The rationale says:

``It would be very difficult for a program-analyzing-program to detect
such an extension. Non-portable programs could easily result.''

In fact the error terminology says this about extending the syntax
when it's allowed:

``Implementations are permitted to define unambiguous extensions to
the syntax of the construct being described. No conforming code can
depend on this extension.  Implementations are required to document
each such extension. All conforming code is required to treat the
syntax as meaningless.''

Thus, the only syntactic extensions allowed would be those that
program analysis programs could detect.

There are some cases where we wish to disallow extensions and some
cases where we don't care. DEFCLASS is an example of one place we wish
to keep people away from. If there are vastly more places where we
don't care, that should be the default. I think it would take a
careful editorial process to decide whether it's easier to defaultly
allow or defaultly disallow. I think this issue is quite different
from that of extensions in general.

			-rpg-

∂09-Mar-89  1539	X3J13-mailer 	Re: Issue: UNSPECIFIED-DATATYPES (Version 2)  
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 9 Mar 89  15:39:49 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA04997; Thu, 9 Mar 89 16:37:40 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA10028; Thu, 9 Mar 89 16:37:35 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903092337.AA10028@defun.utah.edu>
Date: Thu, 9 Mar 89 16:37:28 MST
Subject: Re: Issue: UNSPECIFIED-DATATYPES (Version 2)
To: chapman%aitg.dec@decwrl.dec.com
Cc: x3j13@sail.stanford.edu,
        David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
In-Reply-To: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>, Thu, 9 Mar 89 16:49 EST

I agree with Moon.  Leaving the behavior undefined gives an
implementation permission to do anything it wants, including starting
WWIII.  "Anything" ought to include defining some useful behavior for
the situation, such as asking me if I really want to launch the
missiles.

-Sandra
-------

∂12-Mar-89  1616	X3J13-mailer 	Issue: UNSOLICITED-MESSAGES    
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 12 Mar 89  16:16:40 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 555408; Sun 12-Mar-89 19:14:06 EST
Date: Sun, 12 Mar 89 19:13 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: UNSOLICITED-MESSAGES
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu
In-Reply-To: <8902242237.AA14750@decwrl.dec.com>
Message-ID: <890312191349.9.KMP@BOBOLINK.SCRC.Symbolics.COM>

I agree that this is an important issue.
I am not sure I agree with the proposed solution -- partly because
I don't think it goes nearly far enough, and partly because I think the
wording for the place where it stops encourages might actually encourage
more `abuse' than currently exists.

I think it should be possible to know with certainly that calling EQ,
CONS, or even COMPILE, was not going to do I/O, at least in
the normal case. In exceptional cases, CONS might produce GC warnings
or COMPILE might produce compiler warnings, but never should COMPILE
type out anything like 
 Compiling FOO.
or should EQ type out
 Performing EQ comparison of #<FOO 32> and #<BAR 17>.
Right now, nothing assures me of this and I find that disturbing.
This is the issue which I expected to `fix' this problem, and it does
not. In fact, its suggestion that it's ok to type such messages on
*TERMINAL-IO* may actually encourage what I consider to be an abominable
practice.

I would like it stated clearly that in the `normal situation' no
LISP function is permitted to do I/O unless the manual expressly
permits it.

Further, I think the current proposal permitting unsolicited messages
to go to *TERMINAL-IO* is a bad idea. I don't think unsolicited messages
should ever go directly to *TERMINAL-IO*. I am ammenable to them going to
documented streams which happen to have initial values that are synonym
streams to *TERMINAL-IO*, but 
 - I -don't- want them to be the standard CL streams, so I don't redirect
   them by accident.
 - I -do- want them to not be *terminal-io* so I can redirect them on
   purpose.
Conceivably we could actually make a *JUNK-OUTPUT* which is initially a 
synonym stream to *TERMINAL-IO*, but which is specially permitted to be
NIL to mean don't send the output anywhere, and we should say that all
unsolicited I/O has to go through there.

∂13-Mar-89  0714	X3J13-mailer 	cl-compiler mail
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  07:14:10 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA16287; Mon, 13 Mar 89 08:12:01 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02044; Mon, 13 Mar 89 08:11:59 -0700
Date: Mon, 13 Mar 89 08:11:59 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131511.AA02044@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: cl-compiler mail

I will be sending out the remaining batch of cl-compiler issues today.
I will also put FTP'able copies on host cs.utah.edu in directory
~ftp/pub/cl-compiler/pending.  I'll send out a summary of issues when
I've gotten through them all.

It may be necessary for us to bring revised versions of some of these
proposals to the meeting.  In particular, a few of them have been put
together at the last minute and haven't been reviewed thoroughly yet;
I've marked these as drafts so you'll be able to identify them.  Any
comments or questions should be directed to cl-compiler@sail.stanford.edu.

-Sandra

∂13-Mar-89  0747	X3J13-mailer 	issue COMPILED-FUNCTION-REQUIREMENTS, version 4    
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  07:47:01 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA17004; Mon, 13 Mar 89 08:44:52 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02070; Mon, 13 Mar 89 08:44:48 -0700
Date: Mon, 13 Mar 89 08:44:48 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131544.AA02070@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue COMPILED-FUNCTION-REQUIREMENTS, version 4

Forum:		Compiler
Issue:		COMPILED-FUNCTION-REQUIREMENTS
References:	CLtL p. 32, 76, 112, 143, 438-439
		Issue FUNCTION-TYPE (passed)
		Issue COMPILER-LET-CONFUSION
		Issue EVAL-WHEN-NON-TOP-LEVEL
		Issue LOAD-TIME-EVAL (passed)
		Issue COMPILE-ENVIRONMENT-CONSISTENCY
Category:	CLARIFICATION
Edit History:   V1, 3 Jan 1989 Sandra Loosemore
		V2, 10 Jan 1989, Sandra Loosemore (additional proposal)
		V3, 10 Feb 1989, Sandra Loosemore (new proposal)
		V4, 11 Mar 1989, Sandra Loosemore (fix wording to agree
			with other pending proposals)
Status:		Ready for release


Problem Description:

There is confusion about what functions might be or must be of type
COMPILED-FUNCTION, and what attributes must be true of
COMPILED-FUNCTIONs.  Is the distinction between COMPILED-FUNCTIONs and
other functions only one of representation, or can user programs infer
anything about COMPILED-FUNCTIONs?  Are implementations required to
distinguish between compiled and non-compiled functions?

CLtL defines a COMPILED-FUNCTION as "a compiled code object".  (Issue
FUNCTION-TYPE says only that COMPILED-FUNCTION must be a subtype of
FUNCTION.)  Although it is not explicitly stated, CLtL implies that
compiled code must conform to certain rules; in particular, it states
that all macros are expanded at compile time, and specifies different
behavior for the COMPILER-LET and the EVAL-WHEN special forms
depending on whether they are interpreted or compiled.

The description of COMPILE in CLtL says that "a compiled-function object
[is] produced".  It is not clear to everyone whether this implies that
COMPILED-FUNCTION-P must be true of such functions.  CLtL says nothing
about whether functions defined in files compiled with COMPILE-FILE and
subsequently loaded must be of type COMPILED-FUNCTION.

The two proposals presented below present a simple model of the
compilation process.  A minimal compiler could be implemented to
perform a code walk to apply the indicated transformations to the
function source code.  Of course, most compilers will perform other
transformations as well, such as translating the Lisp source code into
a representation that is more compact or which can be executed more
efficiently. 


Proposal COMPILED-FUNCTION-REQUIREMENTS:TIGHTEN:

(1) Clarify that if a function is of type COMPILED-FUNCTION, the
    following are guaranteed about the function:

    - All macro calls appearing lexically within the function have 
      already been expanded and will not be expanded again when the
      function is called.  (See CLtL p. 143.)  The process of
      compilation effectively turns MACROLET and SYMBOL-MACROLET
      constructs into PROGNs with all instances of the local macros
      in the body fully expanded.

    - The compiler must capture declarations to determine whether
      variable bindings and references appearing lexically within 
      the function are to be treated as lexical or special.

    - COMPILER-LETs nested lexically within the function will not bind 
      any variables when the function is called (CLtL p. 112).  Again,
      the process of compilation effectively turns COMPILER-LET 
      constructs into PROGNs with all macros in the body fully expanded.

    - Lexically nested EVAL-WHENs have been processed as stated in
      proposal EVAL-WHEN-NON-TOP-LEVEL; either the body is treated as
      an implicit PROGN or as the constant NIL.

    - If the function contains lexically nested LOAD-TIME-VALUE forms,
      these have already been pre-evaluated and will not be evaluated
      again when the function is called.

(2) Implementations are free to classify all functions as 
    COMPILED-FUNCTIONs, provided that all functions satisfy the criteria
    listed in item (1).  It is also permissible for functions that are
    not COMPILED-FUNCTIONs to satisfy the above criteria.

(3) Clarify that COMPILE always produces an object of type 
    COMPILED-FUNCTION.  Clarify when functions are defined in a 
    file which is compiled with COMPILE-FILE, and the compiled file is
    subsequently LOADed, objects of type COMPILED-FUNCTION result.


  Rationale:

  This proposal allows users to count on COMPILE and COMPILE-FILE always
  producing objects that are COMPILED-FUNCTION-P.

  It assigns some specific properties to compiled functions.  Users would
  be able to rely on any function which is of type COMPILED-FUNCTION having
  really been (at least partially) compiled.

  It also states what many people believe to be the minimum functionality 
  required of a compiler.


Proposal COMPILED-FUNCTION-REQUIREMENTS:TIGHTEN-COMPILE:

(1) Clarify that functions produced by COMPILE, or defined in a file
    produced by COMPILE-FILE which has been subsequently LOADed, must
    satisfy the same requirements listed in section (1) of proposal
    TIGHTEN.

(2) Clarify that COMPILE always produces an object of type 
    COMPILED-FUNCTION.  Clarify when functions are defined in a 
    file which is compiled with COMPILE-FILE, and the compiled file is
    subsequently LOADed, objects of type COMPILED-FUNCTION result.


  Rationale:

  This proposal allows users to count on COMPILE and COMPILE-FILE always
  producing objects that are COMPILED-FUNCTION-P.

  It also states what many people believe to be the minimum functionality 
  required of a compiler.
  
  However, it allows functions that have not been compiled also to be of
  type COMPILED-FUNCTION.  For implementations that do not use different
  representations for interpreted and compiled functions, it would still
  allow COMPILED-FUNCTION and FUNCTION to be synonymous, even if
  interpreted functions do not satisfy the requirements for compilation.


Current Practice:

It appears that most implementations currently distinguish compiled
versus non-compiled functions on the basis of representation.  It seems
unlikely that any implementation would have problems satisfying the
stated minimum requirements for compilation.

Lucid uses the same representation for both compiled and non-compiled
functions, except there is a bit in the header used to distinguish them.

A-Lisp uses the same representation for both compiled and interpreted
functions and currently labels them both as COMPILED-FUNCTION, but the
implementation of COMPILED-FUNCTION-P could be easily fixed to
distinguish "real" compiled functions.

On the TI Explorer, the COMPILE function can return an object of
either type COMPILED-FUNCTION or LEXICAL-CLOSURE, where the latter
consists of two components -- an environment and a COMPILED-FUNCTION.
There is confusion about whether microcoded functions should be
considered compiled or not.


Cost to implementors:

Unknown, but probably small for either proposal.  Proposal 
TIGHTEN-COMPILE is probably most consistent with current practice.


Cost to users:

Probably minimal.  Since the COMPILED-FUNCTION type specifier is
currently ill-defined, it is hard to imagine that existing programs
can portably rely on any interpretation of what it means that is
inconsistent with what is presented here.


Benefits:

The specification of what the compiler must do is made more explicit.


Discussion:

The FIXNUM and BIGNUM types were also defined in CLtL solely on the
basis of distinguished representations, and that this definition has
proved inadequate for just about all portable usages of these type
specifiers.  Defining COMPILED-FUNCTION solely on the basis of
distinguished representation seems like a bad idea.

David Gray notes:

  We make good use of the type COMPILED-FUNCTION in our implementation,
  but all of the accessor functions for objects of that type are
  non-standard, which makes me wonder if it might be best to just remove
  this type from the standard along with BIGNUM.

One use of the COMPILED-FUNCTION type is in declarations.  A-Lisp and
Lucid, for example, can compile FUNCALL more efficiently if it can be
determined that the function is of type COMPILED-FUNCTION.  However,
in order for such declarations to be really useful, there should be a
way to construct an object which is guaranteed to be of type
COMPILED-FUNCTION.  Both of the proposals presented require COMPILE
and COMPILE-FILE to construct compiled functions.

Sandra Loosemore says:
  I have a marginal preference for proposal TIGHTEN-COMPILE, since it
  gives implementors more flexibility.  To me it's more important that 
  COMPILE and COMPILE-FILE be guaranteed to do something, than that I 
  be able to test whether a function has had those things done to it.

∂13-Mar-89  0749	X3J13-mailer 	issue COMPILER-VERBOSITY, version 6 
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  07:48:54 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA17056; Mon, 13 Mar 89 08:46:44 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02078; Mon, 13 Mar 89 08:46:42 -0700
Date: Mon, 13 Mar 89 08:46:42 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131546.AA02078@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue COMPILER-VERBOSITY, version 6

Forum:	    	Compiler
Issue:		COMPILER-VERBOSITY
References:	CLtL p. 438-329; 426
		issue COMPILER-DIAGNOSTICS
Category:	ENHANCEMENT
Edit History:   V1, 25 Oct 1988, Sandra Loosemore
    	    	V2, 12 Dec 1988, Dan L. Pierson (add USE-CONDITIONS)
    	    	V3, 15 Dec 1988, Dan L. Pierson (expand on conditions)
    	    	V4, 21 Dec 1988, Dan L. Pierson (reword and clarify)
		V5, 06 Jan 1989, Sandra Loosemore (update discussion)
		V6, 26 Jan 1989, Sandra Loosemore (remove USE-CONDITIONS)
Status:		Ready for release


Problem Description:

Implementations vary widely in the amount of information that is printed
out by COMPILE-FILE.  In some situations, it would be useful to control
how much information is printed.


Proposal COMPILER-VERBOSITY:LIKE-LOAD:

Introduce special variables, *COMPILE-VERBOSE* and *COMPILE-PRINT*,
with implementation-dependent initial values.

Add :VERBOSE and :PRINT keyword arguments to the function
COMPILE-FILE, analogous to those for the function LOAD.

The :VERBOSE argument (which defaults to the value of
*COMPILE-VERBOSE*), if true, permits COMPILE-FILE to print a message
in the form of a comment to *STANDARD-OUTPUT* indicating what file is
being compiled and other useful information.

The :PRINT argument (which defaults to the value of *COMPILE-PRINT*),
if true, causes information about top-level forms in the file being
compiled to be printed to *STANDARD-OUTPUT*.  Exactly what is printed
will vary from implementation to implementation, but nevertheless some
information will be printed.

Introduce a special variable *LOAD-PRINT*, which has an initial value of
NIL.  State that the default value of the :PRINT argument to LOAD is
*LOAD-PRINT* (rather than NIL).


Rationale:

This proposal makes COMPILE-FILE behave like LOAD.  There is already
some precedent for doing this (for example, issue COMPILE-FILE-PACKAGE,
which makes COMPILE-FILE as well as LOAD rebind *PACKAGE*).

Adding the *LOAD-PRINT* variable allows the printing of messages by
LOAD to be controlled either on a global or a per-call basis.


Current Practice:

COMPILE-FILE prints out progress messages in nearly all
implementations.

Lucid provides a :MESSAGES keyword argument to COMPILE-FILE, which can
either be a stream to send messages to, or NIL to suppress messages.
The default value is T, which sends messages to "the standard terminal
device".

On the TI Explorer, COMPILE-FILE displays the name of the function
being compiled when the option :VERBOSE T is given or special variable
COMPILER:COMPILER-VERBOSE is true.  (In other words, they use :VERBOSE
to mean what this proposal says to use :PRINT for.)

Symbolics Cloe already has a *LOAD-PRINT* variable.


Cost to implementors:

This is an incompatible change for some implementations.  While the
changes required should be conceptually simple, their implementation
may involve a significant amount of grunt work.  At least two
implementations already provide some similar mechanism for suppressing
messages.


Cost to users:

Some (non-portable) user code may break in implementations where this
is an incompatible change.

No user code should be broken by the addition of the *LOAD-PRINT*
variable, since the default behavior for the :PRINT keyword to LOAD 
is unchanged.


Benefits:

Users are given a portable way to control how much information is printed
by COMPILE-FILE.


Discussion:

This issue addresses an extension to the language.  If this proposal
is not accepted, the standard will simply continue not to say anything
about whether COMPILE-FILE can print progress messages, or what stream
such messages are directed to.

∂13-Mar-89  0748	X3J13-mailer 	issue COMPILER-DIAGNOSTICS, version 9    
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  07:48:14 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA17028; Mon, 13 Mar 89 08:46:02 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02075; Mon, 13 Mar 89 08:45:59 -0700
Date: Mon, 13 Mar 89 08:45:59 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131545.AA02075@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue COMPILER-DIAGNOSTICS, version 9

Forum:		Compiler
Issue:		COMPILER-DIAGNOSTICS
References:	CLtL p. 438-439, 62, 69, 160, 161
		Condition System, Revision #18
	    	S:>KMP>cl-conditions.text.34
	    	Issue GC-MESSAGES
	    	Issue RETURN-VALUES-UNSPECIFIED
	    	Issue COMPILER-VERBOSITY
Category:	CLARIFICATION, ENHANCEMENT
Edit History:   V1, 15 Oct 1988, Sandra Loosemore
	    	V2, 19 Oct 1988, Sandra Loosemore (minor fixes)
	    	V3, 25 Oct 1988, Sandra Loosemore (input from Pitman & Gray)
	    	V4, 01 Nov 1988, Sandra Loosemore (fix typos)
	   	V5, 15 Dec 1988, Dan L. Pierson   (new condition types)
	   	V6, 15 Dec 1988, Sandra Loosemore (additions, fix wording)
	    	V7, 16 Dec 1988, Dan L. Pierson   (minor cleanup)
		V8, 07 Jan 1989, Sandra Loosemore (expand discussion)
		V9, 26 Jan 1989, Sandra Loosemore (simplify)
Status:		Ready for release
     
Problem Description:

It is unclear whether various diagnostics issued by the compiler are 
supposed to be true errors and warnings, or merely messages.

In some implementations, COMPILE-FILE handles even serious error
situations (such as syntax errors) by printing a message and then
trying to recover and continue compiling the rest of the file, rather
than by signalling an error.  While this user interface style is just
as acceptable as invoking the debugger, it means that a normal return
from COMPILE-FILE does not necessarily imply that the file was
successfully compiled.

Many compilers issue warnings about programming style issues (such as
binding a variable that is never used but not declared IGNORE).
Sometimes these messages obscure warnings about more serious problems,
and there should be some way to differentiate between the two.  For
example, it should be possible to suppress the style warnings.

Also, neither CLtL nor issue RETURN-VALUES-UNSPECIFIED states what the 
return value from COMPILE-FILE should be.


Proposal COMPILER-DIAGNOSTICS:USE-HANDLER:

(1) Introduce a new condition type, STYLE-WARNING, which is a subtype
    of WARNING.

(2) Clarify that ERROR and WARNING conditions may be signalled within 
    COMPILE or COMPILE-FILE, including arbitrary errors which may 
    occur due to compile-time processing of (EVAL-WHEN (COMPILE) ...) 
    forms or macro expansion.

    Considering only those conditions signalled -by- the compiler (as
    opposed to -within- the compiler),

    (a) Conditions of type ERROR may be signalled by the compiler in
        situations where the compilation cannot proceed without
        intervention.

        Examples:
	    file open errors
   	    syntax errors

    (b) Conditions of type WARNING may be signalled by the compiler in 
        situations where the standard explicitly states that a warning must,
        should, or may be signalled; and where the compiler can determine 
        that a situation that "is an error" would result at runtime.

        Examples:
	    violation of type declarations
	    SETQ'ing or rebinding a constant defined with DEFCONSTANT
	    calls to built-in Lisp functions with wrong number of arguments
	        or malformed keyword argument lists
	    referencing a variable declared IGNORE
	    unrecognized declaration specifiers

    (c) The compiler is permitted to signal diagnostics about matters of
        programming style as conditions of type STYLE-WARNING.  Although 
        STYLE-WARNINGs -may- be signalled in these situations, no 
        implementation is -required- to do so.  However, if an 
        implementation does choose to signal a condition, that condition 
        will be of type STYLE-WARNING and will be signalled by a call to 
        the function WARN.

        Examples:
	    redefinition of function with different argument list
	    unreferenced local variables not declared IGNORE
	    declaration specifiers described in CLtL but ignored by 
	        the compiler

(3) Require COMPILE and COMPILE-FILE to handle the ABORT restart by
    aborting the smallest feasible part of the compilation.  State that
    both COMPILE and COMPILE-FILE are allowed to establish a default
    condition handler.  If such a condition handler is established,
    however, it must first resignal the condition to give any
    user-established handlers a chance to handle it.  If all user error
    handlers decline, the default handler may handle the condition in an
    implementation-specific way; for example, it might turn errors into
    warnings.

(4) Specify that COMPILE-FILE returns two values.  The first value
    is the truename of the output file, or NIL if the file could not be
    created.  The second value is T if the file was compiled without
    errors, or NIL if errors were signalled during compilation.


Rationale:

Introducing the STYLE-WARNING condition allows handlers to distinguish
between potentially serious problems and mere kibitzing on the part of
the compiler.

Requiring any condition handlers established by the compiler to resignal
the condition before proceeding with any implementation-specific action
gives user error handlers a chance to override the compiler's default
behavior.  For example, the user error handler could invoke a restart
such as ABORT or MUFFLE-WARNING.

Requiring the compiler to handle the ABORT restart reflects what
several implementations already do (although probably not using this
mechanism).  The intent of the wording is to allow an implementation
to abort the entire compilation if it is not feasible to abort a
smaller part.

Requiring a second success-p value to be returned from COMPILE-FILE
gives the user some indication of whether there were serious problems
encountered in compiling the file.


Test Case/Example:

Here is an example of how COMPILE-FILE might set up its condition
handlers.  It establishes an ABORT restart to abort the compilation
and a handler to take implementation-specific action on ERROR
conditions.  Note that INTERNAL-COMPILE-FILE may set up additional
ABORT restarts.

    (defvar *output-file-truename* nil)

    (defun compile-file (input-file &key output-file)
      (let ((*output-file-truename*    nil)
 	    (errors-detected           nil))
	(with-simple-restart (abort "Abort compilation.")
	  (handler-bind ((error  #'(lambda (condition)
				     (setq errors-detected t)
				     (signal condition)
				     ...)))
	    (internal-compile-file input-file output-file)))
	(values *output-file-truename*
		errors-detected)))



Current Practice:

No implementation behaves exactly as specified in this proposal.

In VaxLisp, COMPILE-FILE handles most compile-time errors without
invoking the debugger.  (It gives up on that top-level form and moves on
to the next one.)  Instead of signalling errors or warnings, it simply
prints them out as messages.

In Lucid Common Lisp, COMPILE-FILE invokes the debugger when it encounters
serious problems.  COMPILE-FILE returns the pathname for the output file.

Symbolics Genera usually tries to keep compiling when it encounters errors;
so does Symbolics Cloe.

On the TI Explorer, the compiler tries to catch most errors and turn
them into warnings (except for errors on opening a file), but the user
can change special variable COMPILER:WARN-ON-ERRORS to NIL if he wants
to enter the debugger on an error signalled during reading, macro
expansion, or compile-time evaluation.  The true name of the output
file is returned as the first value.  A second value indicates whether
any errors or warnings were reported.

IIM Common Lisp's compiler handles errors using a resignalling mechanism
similar to what is described here.


Cost to implementors:

The cost to implementors is not trivial but not particularly high.  This
proposal tries to allow implementations considerable freedom in what
kinds of conditions the compiler must detect and how they are handled,
while still allowing users some reasonably portable ways to deal with
compile-time errors.


Cost to users:

This is a compatible extension.  This proposal may cause users to see
some small differences in the user interface to the compiler, but
implementations already vary quite widely in their approaches.  Some
users will probably have to make some minor changes to their code.

Adding the STYLE-WARNING type may cause conflicts with programs
already using that name.


Benefits:

Users are given a way to detect and handle compilation errors, which
would simplify the implementation of portable code-maintenance
utilities.  The behavior of the compiler in error situations is made
more uniform across implementations.


Discussion:

The issue of whether the compiler may print normal progress messages
is discussed in detail in a separate issue, COMPILER-VERBOSITY.

∂13-Mar-89  0815	X3J13-mailer 	issue CONSTANT-COMPILABLE-TYPES, version 8    
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  08:15:04 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA17983; Mon, 13 Mar 89 09:12:55 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02083; Mon, 13 Mar 89 09:12:49 -0700
Date: Mon, 13 Mar 89 09:12:49 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131612.AA02083@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue CONSTANT-COMPILABLE-TYPES, version 8

Forum:		Compiler
Issue:		CONSTANT-COMPILABLE-TYPES
References:	CLtL pp. 56, 77-80, 324
		Issue CONSTANT-MODIFICATION
		Issue CONSTANT-CIRCULAR-COMPILATION
		Issue CONSTANT-ARRAY-ATTRIBUTES
		Issue QUOTE-SEMANTICS
		Issue LOAD-OBJECTS
Category:	CLARIFICATION, ADDITION
Edit history:	11/07/88, V1 by Cris Perdue
		11/14/88, V2 by Cris Perdue
		11/22/88, V3 by Cris Perdue
		12/20/88, V4 by Cris Perdue
		01/06/89, V5 by Sandra Loosemore (minor editorial
			clarifications, expand discussion)
		03/05/89, V6 by Cris Perdue (more response to comments,
			especially from Moon and and from Loosemore)
                03/05/89, V7 by Loosemore (more editorial tweaks)
		03/13/89, V8 by Loosemore (discussion)
Status:		Ready for release

Problem description:

CLtL does not specify what objects can be in compiled constants and it
does not say what relationship there is to be between the
constant passed to the compiler and the one that is established by
compiling and then loading its file.  Relevant remarks in CLtL
concerning file compilation and the definition of QUOTE suggest that
the compiler handles constants in ways that are not actually possible.

Introduction to the proposal:

The proposal CONSTANT-COMPILABLE-TYPES:SPECIFY attempts to spell out
what types can appear in compiled constants, and what it means when
they appear.  Unless stated otherwise, in this proposal where the term
"constant" is used, it means a quoted or self-evaluating constant, not
a named (defconstant) constant.

The key is a definition of a form of equivalence between Lisp objects,
"similarity as constants".  Code passed through the file compiler and
then loaded must behave as though quoted constants in it are "similar"
to quoted constants in the corresponding interpreted "source" code.

Because it is legitimate to compile in one address space and load into
a different one, it is necessary for the constraints to be defined
across address spaces.  This proposal only concerns quoted constants
to be processed by COMPILE-FILE.  Some other issues related to file
compilation are CONSTANT-COLLAPSING, CONSTANT-CIRCULAR-COMPILATION,
and QUOTE-SEMANTICS.

Some implementations "lose information" about some constants during
compilation.  Typically all constant arrays become simple arrays
during the process of compiling and loading.  We try to balance the
desire for more functionality against the effort required from
implementors.

Comments within the text of the proposal are enclosed in double angle
brackets, <<like this>>.

Proposal:  CONSTANT-COMPILABLE-TYPES:SPECIFY

An object may be used as a quoted constant processed by COMPILE-FILE
if the compiler can guarantee that the resulting constant established
by loading the compiled file is "similar as a constant" to the
original.  Treatment of uninterned symbols must be consistent across
the entire file as described below.  There also is a constraint on
arrays which is not symmetrical; compilation can make arrays
"simpler", but not "less simple".  (See below for the definition.)

We refer below to "quoted constants" or just "constants".  In this
section these terms refer to objects appearing in expressions of the
form (QUOTE <object>), to objects used as self-evaluating forms, and
to objects appearing in code at locations described as "not
evaluated".

Some types such as streams are not supported in constants.  Put
another way, an object containing one of these is not considered
similar as a constant to any other object.  Some implementations may
support them and define how they are treated.  For any object that
appears in a constant, but is not supported by the language as part of
a constant, the behavior of the compiler is unspecified; either the
the compiler and/or loader will handle that constant (in an
implementation-dependent manner) or the compiler will detect the
situation and signal an error.

Of the types supported in constants, some are treated as aggregate
objects.  For these types, being similar as constants is defined
recursively.  We say that an object of these types has certain
attributes, and to be similar as a constant to another object, the
values of the corresponding attributes of the two objects must also be
similar as constants.

This kind of definition has problems with any circular or "infinitely
recursive" object such as a list that is an element of itself.  We
use the idea of depth-limited comparison, and say that two
objects are similar as constants if they are similar at all finite
levels.  This idea is implicit in the definitions below, and applies
in all the places where attributes of two objects are required to be
similar as constants.

Here we define the notion of two objects being "similar as constants",
organizing the definition by type, and note additional constraints
that the compiler and loader working together must meet:

Number

  If either of the two objects is a number, both must be of the same
  type and must represent the same mathematical value.
  
Character

  If either of the two objects is a character, both must be character
  objects that represent the same character.  <<Note that this
  definition has to depend on the results of the Character Set
  proposals.>>

Random-state
  
  Let us say that two random-states are functionally equivalent if 
  applying RANDOM to them repeatedly always produces the same 
  pseudo-random numbers in the same order.  
  
  Two random-states are similar as constants exactly if copies of them
  made via MAKE-RANDOM-STATE are functionally equivalent.

  Note that a constant random-state object cannot be used as the "state"
  argument to the function RANDOM (because RANDOM side-effects this
  data structure).

Symbol

  A symbol can only be similar to a symbol.  References to interned
  symbols are "by name".  <<See issue COMPILE-FILE-SYMBOL-HANDLING for
  details.>>

  If a symbol is not interned, i.e. its home package is NIL, it is
  treated in a rather special way.  To be similar as a constant to
  another symbol, both symbols must be uninterned and have the same
  name.
  
  Constants that contain uninterned symbols have to satisfy an extra
  constraint.  Consider the set of places in a constant that refer to
  the same (EQ) uninterned symbol.  In any similar constant, the
  corresponding places must also all be EQ -- no more places and no
  fewer.  Moreover, COMPILE-FILE must arrange for the EQness of all 
  constant uninterned symbols that appear in the file to be preserved,
  even if they are referenced in separate constants.

  Because hash keys can be aggregate objects and because we treat hash
  tables as unordered sets of <key, value> pairs, similarity of hash
  tables is more complex.  See under "Hash Tables", below, for the
  definition.

Package

  A package can only be similar as a constant to a package.  References
  to packages are permitted in any constant.  References to packages are
  "by name": two packages are similar as constants when their names are
  similar as constants.  Within a Lisp "address space", packages with
  the same name are EQ.
  
  At load time, the package becomes the same as returned by
  FIND-PACKAGE, given the package name.  An error is signalled if no
  package of that name exists at load time.

  
AGGREGATE TYPES
---------------
  
For each of the types listed below, if either object is of the given
type, the two objects are similar as constants exactly if the other is
of that type and the values of all of the specified attributes are
similar as constants.

The attributes listed here can be called the "Basic Attributes" of
objects of each of these types.

Cons	     CAR, CDR.

Array	     For 1-dimensional arrays:
	     LENGTH, ARRAY-ELEMENT-TYPE, and ELT for all legal indices.

	     For arrays of other dimensions:
	     ARRAY-DIMENSIONS, ARRAY-ELEMENT-TYPE, AREF for all legal
	     indices.

	     An array of type SIMPLE-ARRAY can only be similar as a
	     constant to an array of type SIMPLE-ARRAY.  However, we
	     allow the file-compiler a bit of latitude here.  Where
	     constants in source code are displaced, have fill
	     pointers, or are adjustable, constants in the code
	     resulting from compilation and loading are permitted to
	     lack any or all of these qualities.

Hash Table   Keys and value pairs.  The table's test is unchanged
	     also.  If the file compiler is given a constant containing a
	     a hash table that has keys that are similar as
	     constants, the consequences are undefined.

	     Consider a hash table as an unordered set of key and
	     value pairs.  Two hash tables are similar as constants
	     exactly if there is a one-to-one correspondence between
	     the key and value pairs of each and a one-to-one
	     correspondence between the uninterned symbols of each
	     such that the two keys of each corresponding pair are
	     similar as constants and the two values are also similar
	     as constants.  The correspondence of uninterned symbols
	     must be consistent with the correspondence defined for
	     the entire set of constants in the file.

Pathname     Each pathname component.

OTHER TYPES
-----------

Stream, Compiled-Function, Readtable, Generic-function, Method
             Objects of these types are not supported in compiled
             constants.

Function     Only function constants that are not compiled-functions
	     and do not close over any (lexical) variables are
	     supported in compiled constants.

	     Two such functions are similar as constants if their
	     SOURCE-LAMBDA-EXPRESSIONs are similar as constants.

Structure, Standard-object
             <<There is a cl-cleanup issue, LOAD-OBJECTS, pending
             which proposes a mechanism for dealing with objects.>>
             For structure instances with no method defined at compile
             time for MAKE-LOAD-FORM, the slot values and the name of
             structure type (a symbol reference) are recorded by the
             compiler and reconstructed by the loader.


Examples:

If source code contains a constant that could PRINT as (#1=#:FOO
#2=#:FOO #1# #2#), the constant resulting from compiling and loading
that code would have to be PRINTable as (#1=#:FOO #2=#:FOO #1# #2#).

If we make a hash table H, set three variables A, B, and C to
different uninterned symbols named FOO, and enter keys and values as
follows:

(setf (gethash a h) b)
(setf (gethash b h) a)
(setf (gethash c h) c)

If H appears in a compiled constant, after compiling and loading it,

(let ((value (list)))
  (maphash #'(lambda (x y) (push (list x y) value)) h)
  value)

could print as

((#1=#:FOO #2=#:FOO) (#2# #1#) (#3=#:FOO #3#))

but not as

((#1=#:FOO #2=#:FOO) (#2# #3=#:FOO) (#3# #1#))


Rationale:

For the benefit of users, this proposal tries to define a fairly large
set of types that all Common Lisp implementations are to handle.  It
also attempts to leave room for implementations to differ.  Some
implementations have made opposing choices because the language
doesn't specify one over the other.  Some implementations already
handle constants that this proposal defines as not legal in Common
Lisp programs, and that is useful to users of those systems.
Different implementors have different amounts of resources to apply to
their system, and implementations differ in their whole approach in
some cases.

This proposal appears to reflect user demand and appears not to exceed
the capabilities of most implementations of the language.

The proposal ensures that all references to the same uninterned symbol
within a file will all map to references to just one uninterned symbol
after compiling and loading.  This is needed to support PCL.


Current practice:

>From Gail Zacharias (Nov 14): "Coral pretty much implements this
proposal (I think we currently coalesce hash table keys, but that's
just a bug that will be fixed).  We also fasdump packages (using the
package name) and compiled functions (but not foreign functions).  For
symbols, we dump the name, and if (roughly speaking) the symbol would
get printed with a package prefix, we also dump the package name and
load the symbol into that package (otherwise it gets loaded into the
current load-time package)."

>From David Gray (Nov 9): "The Explorer can compile constant functions,
read tables, and hash tables; an error is signalled for a stream.  A
package object used to break the compiler but in release 5 it has been
fixed to generate instructions to call FIND-PACKAGE on the package
name at load time."  (Nov 15): [The Explorer does not guarantee
retention of displaced-to and displaced-index-offset attributes.]
"The Explorer also does not currently support dumping closures (either
compiled or evaluated), although non-closure compiled functions can be
dumped."

>From David Moon (Jan 24): "Symbolics Genera current practice: aside
from some current bugs we have with circular structures of certain
types and with preserving the identity of CONSes under EQ, this is
more or less consistent with our current practice, if you made the
changes implied by my earlier comments.  We preserve the :displaced-to
and :fill-pointer array attributes.  I doubt that we do what the
proposal says for hash-tables, readtables, and random-states.  We
support dumping compiled and interpreted functions, but not closures,
which in effect means we don't support dumping functions."

>From Sandra Loosemore (Mar 3): "UCL currently can handle only
constants that are of type number, character, symbol, cons,
simple-vector, or string (which it turns into simple-string).  It
signals an error if an attempt is made to compile any other kind of
object as a constant."


Adoption cost:

Not known.  Probably moderate or low -- for most implementations.  The
cost would be to implementors rather than users since this part of the
language is currently underspecified.  The author believes the cost
will be reasonable for KCL, an implementation where there is some
concern about this issue.

This proposal is close to compatible with the Franz, Lucid, Coral,
Texas Instruments, and Symbolics implementations.  It is probably
compatible or nearly compatible with other "Lisp Machine"
implementations.


Benefits:

Users would be able to use aggregate objects in constants with
confidence about the behavior of their code.


Conversion cost:

Where this proposal *requires* different behavior than an existing
implementation, there is a conversion cost for users of that
implementation.  It appears that this cost will be small, less than
the cost of leaving things unspecified.


Esthetics:

Since there is no adequate definition at present, a fuller definition
would be more esthetic.


Discussion:

This proposal does leave some user-visible attributes of objects
unspecified across the compile-and-load process, except that they must
be consistent with the attributes that must be retained.  This
situation is a compromise between the desire for full specification on
the one hand, and on the other hand the desire to leave freedom for
different implementations to remain different and to support some
optimizations such as compacting hash tables and "simplifying" arrays.

Proposals will be entertained for tighter specification of datatypes
such as arrays.

The full extension of the concept of coalescing of constants is to say
that they can be coalesced exactly when they are similar as constants.

Comparing functions semantically is intertwined with the specification
of what conforming programs and implementations are allowed to do.
This proposal does not attempt to do that since compiled functions are
not supported by this proposal in compiled constants.

The definition of similarity for random-states supports the
possibility of random states that are immutable because of being in
compiled constants.

Readtables need not be supported by an implementation.  If a readtable
contains only symbols to represent functions, here is Cris Perdue's
suggested spec for similarity of readtables:

Character syntax type for each character in the table;
function for each readmacro character, mappings for
dispatch macros; whether terminating or nonterminating
for each readmacro.

Interest has been expressed by a number of people including users, in
support for user-definable "dumping" of CLOS objects and structure
instances.  The cleanup issue LOAD-OBJECTS deals with this.

This subsumes the issue CONSTANT-ARRAY-ATTRIBUTES.

The main point of disagreement on this proposal over its handling
of constant functions.

Sandra Loosemore says:

  I plan to submit an amendment to this proposal which would remove the
  requirement that the compiler be able to dump non-compiled, non-closed
  functions.  The reason for removing this requirement is that there is
  no way to portably construct an object which is guaranteed to be a
  non-compiled, non-closed function.  Note that implementations are
  permitted to make all functions COMPILED-FUNCTIONs.

Dick Gabriel says:

  I guess I pretty strongly object to leaving functions out of the list
  of constants that can appear in compiled code. The part that's
  disturbing is that such non-Lispy things like arrays, hashtables, and
  pathnames get better treatment than functions, the most Lispy part of
  Common Lisp. I wonder how many implementations will be forced to come
  within an inch of the required functionality to implement a first-rate
  CLOS?

  The specification of the subset of functions that are acceptable as
  compiled constants cannot be tested for within Common Lisp itself.

  I suggest we ask implementors (Lucid included) to bite the bullet and
  handle this case correctly. Won't our grandchildren appreciate us
  treating Common Lisp like Lisp and not like PASCAL?

If we were to specify that all functions could appear as constants, we
would also need to clarify whether the closed-over variable bindings
become immutable, and also deal with whether bindings that are closed
over more than one function retain their uniqueness.  Also, the cost
to implementors to add support for dumping non-interpreted functions
may be quite high.

∂13-Mar-89  0821	X3J13-mailer 	issue CONSTANT-CIRCULAR-COMPILATION, version 7
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  08:21:42 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA18436; Mon, 13 Mar 89 09:19:31 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02090; Mon, 13 Mar 89 09:19:28 -0700
Date: Mon, 13 Mar 89 09:19:28 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131619.AA02090@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue CONSTANT-CIRCULAR-COMPILATION, version 7

Forum:		Compiler
Issue:		CONSTANT-CIRCULAR-COMPILATION
References:	Issue CONSTANT-COLLAPSING
		Issue QUOTE-SEMANTICS
Category:	CLARIFICATION, ADDITION
Edit History:   V1, 07 Nov 1988, Sandra Loosemore
		V2, 14 Nov 1988, Cris Perdue
		V3, 12 Dec 1988, Sandra Loosemore (merge versions 1 and 2)
		V4, 03 Jan 1989, Sandra Loosemore (add PRESERVE-SHARING-ONLY)
		V5, 06 Jan 1989, Sandra Loosemore (minor wording changes)
		V6, 08 Feb 1989, Sandra Loosemore (replace FLAG with YES)
                V7, 11 Mar 1989, Sandra Loosemore (error terminology)
Status:		Ready for release


Problem Description:

CLtL does not specify whether constants containing circular or
recursive references may be compiled.  It is also not clear whether
the compiler must preserve sharing of EQ substructures; that is, whether
subobjects that are EQ in the source code must remain EQ after being
compiled.

The proposals below apply to constants appearing in a file compiled by
COMPILE-FILE.  If proposal QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE
passes, then the same constraints would apply to all constants.  The
minimal scope over which sharing would be required to be detected is
over a single call to EVAL or COMPILE.

In the proposals that follow, "preserving EQness" means that
subobjects that are EQ in the source code must remain EQ after being
compiled; that is, things don't get "less EQ" after compilation.
(Note that coalescing of constants implies that things may get "more
EQ".)


Proposal CONSTANT-CIRCULAR-COMPILATION:NO

State that the consequences are undefined if an object containing a
circular reference appears as a constant to be compiled.  State that
the compiler is not required to preserve EQness of substructures.

  Rationale:

  This proposal would not require any existing implementation to change.

  Disallowing portable programs from containing circular constants
  allows compiled file loaders to use somewhat simpler implementation
  strategies (for example, to build constants in a strict bottom-up
  fashion).


Proposal CONSTANT-CIRCULAR-COMPILATION:PRESERVE-SHARING-ONLY

State that the consequences are undefined if an object containing a
circular reference appears as a constant to be compiled.  State that
the compiler is required to preserve EQness of substructures within a
file compiled with COMPILE-FILE.

  Rationale:

  Disallowing portable programs from containing circular constants
  allows compiled file loaders to use somewhat simpler implementation
  strategies (for example, to build constants in a strict bottom-up
  fashion).

  Some programs (such as PCL) have come to depend on COMPILE-FILE 
  preserving the EQness of uninterned symbols, and it is cleaner
  to require sharing to be preserved in general instead of making
  symbols be a special case.  Requiring sharing to be preserved still
  allows loaders to build constants bottom-up.


Proposal CONSTANT-CIRCULAR-COMPILATION:YES

State that objects containing circular references may legitimately
appear as constants to be compiled.  State that the compiler is
required to preserve EQness of substructures within a file compiled
with COMPILE-FILE.

  Rationale:

  Users seem to expect this functionality, and some implementations 
  already provide it.


Current Practice:

A-Lisp preserves EQness of substructures (since it makes an effort to
collapse isomorphic structures) but signals an error if an attempt is
made to compile a circular constant.  PSL and Utah Common Lisp both
get stuck in an infinite loop if an attempt is made to compile a
reentrant structure.  The TI Explorer compiler is able to reproduce
recursive lists and arrays, but currently hangs in a loop on a
circular list.  Neither the Explorer nor Symbolics Genera 7.x detects
EQness of list CDRs.  Lucid handles circular constants correctly.
Franz uses a flag to control whether or not to attempt to detect
circular constants.  KCL handles circular structures, but only detects
sharing of top-level structure (it does not traverse constants to look
for shared substructure).


Cost to implementors:

We know of no implementation that would have to change under proposal
NO.  

For proposal YES, some implementations would require sweeping
changes; in some cases a completely different dumper/loader strategy
would have to be implemented.

The cost of proposal PRESERVE-SHARING-ONLY would fall somewhere in
between.


Cost to users:

The situation now is that programs which depend upon circularity or
sharing of substructure being preserved by the compiler are already
nonportable.  Proposal NO simply formalizes the status quo.  Proposal
YES would offer users functionality that is currently not portable.


Benefits:

An area of ambiguity in the language is removed.


Discussion:

The issue of compiler speed is largely a red herring on this issue;
the overhead of detecting circularities is generally quite small.  The
main question is whether we should require some implementations to
completely redo their compiler/loader interface in order to support
circular constants.  

It has been argued that any "serious" implementation will support
circular constants anyway, because of customer demand.  However, since
there appears to be only one implementation (Lucid) that now
implements proposal YES in its full generality, perhaps the demand for
this feature is not really all that strong.

Earlier drafts of this writeup contained a proposal FLAG which would
have added a variable *COMPILE-CIRCLE*, similar to *PRINT-CIRCLE*.
However, there were unresolved problems about what would happen if the
value of this variable were altered within the file being compiled,
and it was generally agreed that this proposal didn't have any
particular advantages over proposal YES and just introduced
unnecessary hairiness.

Since it is usually fairly simple to detect circular constants,
Loosemore would support an amendment to proposals NO and
PRESERVE-SHARING-ONLY to change the first sentence to read:

  State that the consequences are unspecified if an object containing
  a circular reference appears as a constant to be compiled.  
  Implementations must either correctly handle the circular reference
  or signal an error.  

This is similar to the language which is already used in proposal
CONSTANT-COMPILABLE-TYPES:SPECIFY.

∂13-Mar-89  0824	X3J13-mailer 	issue CONSTANT-COLLAPSING, version 5
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  08:24:21 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA18594; Mon, 13 Mar 89 09:22:09 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02093; Mon, 13 Mar 89 09:22:05 -0700
Date: Mon, 13 Mar 89 09:22:05 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131622.AA02093@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue CONSTANT-COLLAPSING, version 5

Forum:		Compiler
Issue:		CONSTANT-COLLAPSING
References:	CLtL p. 78, 87
		Issue CONSTANT-MODIFICATION
		Issue CONSTANT-COMPILABLE-TYPES
		Issue EQUAL-STRUCTURE
		Issue QUOTE-SEMANTICS
Category:	CHANGE
Edit History:   V1, 07 Nov 1988, Sandra Loosemore
		V2, 12 Dec 1988, Sandra Loosemore
		V3, 03 Jan 1989, Sandra Loosemore
		V4, 06 Jan 1989, Sandra Loosemore
		V5, 11 Mar 1989, Sandra Loosemore
Status:		Ready for release


Problem Description:

CLtL states that an implementation is permitted to "collapse" or
coalesce constants appearing in code to be compiled if they are EQUAL.
The definition of EQUAL does not permit coalescing of more general
isomorphic data structures (such as arrays and structures), which is
often desirable.

Issue QUOTE-SEMANTICS deals with whether coalescing may be performed
only by COMPILE-FILE, or by COMPILE and EVAL as well.  If proposal 
QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE passes, then coalescing could be
performed on all constants.  

CLtL says: "An object is considered to be a constant in code to be
compiled if it is a self-evaluating form or contained in a QUOTE
form".


Proposal CONSTANT-COLLAPSING:GENERALIZE:

State the an implementation is permitted to coalesce constants
appearing in code to be compiled if they are equivalent under the
relationship defined in proposal CONSTANT-COMPILABLE-TYPES:SPECIFY.


Rationale:

There is little reason why implementations should not be allowed to
perform more general collapsing of structures, since the arguments
against doing so also apply to collapsing of EQUAL structures, which
is already permitted.  The arguments for coalescing of EQUAL structures
(primarily space reduction) also apply to coalescing of structures that
are equivalent under a more general coalescing predicate.


Current Practice:

Both PSL/PCLS and A-Lisp collapse isomorphic arrays and structures,
and certain other data types that are defined internally as structures
(RANDOM-STATEs, for example).  Lucid Common Lisp also uses a more
general coalescing predicate than EQUAL.


Cost to implementors:

None.  This extends the range of permitted behavior for
implementations but does not require any implementation to change.


Cost to users:

Programs that depend on objects not being coalesced except when they
are EQUAL may break under this proposal.  The only way one would be
able to detect that coalescing has taken place is if objects that were
not EQ in the source file become EQ after compilation; accessors on
the objects would return the same values regardless of whether or not
coalescing has taken place.


Benefits:

Collapsing of isomorphic arrays may lead to significant memory savings
in some applications.


Discussion:

This proposal depends heavily on issue CONSTANT-COMPILABLE-TYPES.

Some people believe that if the definition of EQUAL weren't "broken",
there wouldn't be any need for this proposal.

There is no inherent reason why the "coalescing predicate" must be the
same as the relationship used by the compiler/loader to construct
equivalent copies of objects of constants, but making the same rules
be applied in both situations simplifies the language somewhat.

∂13-Mar-89  0840	X3J13-mailer 	Issue: UNSOLICITED-MESSAGES    
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 13 Mar 89  08:40:09 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Mon, 13 Mar 89 11:34:05 EST
Date: Mon, 13 Mar 89 11:35 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Issue: UNSOLICITED-MESSAGES
To: Kent M Pitman <KMP@stony-brook.scrc.symbolics.com>
Cc: chapman%aitg.DEC@decwrl.dec.com, x3j13@sail.stanford.edu
In-Reply-To: <890312191349.9.KMP@BOBOLINK.SCRC.Symbolics.COM>
Message-Id: <19890313163525.7.BARMAR@OCCAM.THINK.COM>

    Date: Sun, 12 Mar 89 19:13 EST
    From: Kent M Pitman <KMP@stony-brook.scrc.symbolics.com>

    I agree that this is an important issue.
    I am not sure I agree with the proposed solution -- partly because
    I don't think it goes nearly far enough, and partly because I think the
    wording for the place where it stops encourages might actually encourage
    more `abuse' than currently exists.

    I think it should be possible to know with certainly that calling EQ,
    CONS, or even COMPILE, was not going to do I/O, at least in
    the normal case. 

Do progress notes in the wholine count as output?  If not, why not?  If
so, are you proposing that they be prohibited?  In Genera, calling
COMPILE displays "Compiling <name>" in the wholine, and calling
READ-CHAR on a console stream displays "User Input" in the wholine.  I
like these things, but I think it will be difficult to express this
distinction in general enough terms in the standard.

		     In exceptional cases, CONS might produce GC warnings
    or COMPILE might produce compiler warnings, but never should COMPILE
    type out anything like 
     Compiling FOO.
    or should EQ type out
     Performing EQ comparison of #<FOO 32> and #<BAR 17>.
    Right now, nothing assures me of this and I find that disturbing.

Why is this problem unique to Lisp?  Is there any wording in the C
standard that explicitly prohibits malloc() from causing output?  I
doubt it, yet I don't think they find this disturbing.

I think market forces should be enough to prevent really silly
unsolicited messages, just as all serious Lisp implementations have a GC
even though CLtL never mentions it.

                                                barmar

∂13-Mar-89  0834	X3J13-mailer 	issue LOAD-TIME-EVAL, version 11    
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  08:34:06 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA18990; Mon, 13 Mar 89 09:31:55 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02140; Mon, 13 Mar 89 09:31:50 -0700
Date: Mon, 13 Mar 89 09:31:50 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131631.AA02140@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue LOAD-TIME-EVAL, version 11

On this issue, we've come up with an improved version of the proposal that
was accepted at the January meeting.

Forum:		Compiler
Issue:          LOAD-TIME-EVAL
References:     #, (p. 356),  (EVAL-WHEN (LOAD) ...) (p. 69-70)
		issue SHARP-COMMA-CONFUSION
Category:       ADDITION
Edit history:   06-Jun-87, Version 1 by James Kempf
                17-Jul-87, Version 2 by James Kempf
                12-Nov-87, Version 3 by Pitman (alternate direction)
                01-Feb-88, Version 4 by Moon
                  (from version 2 w/ edits suggested by Masinter)
                06-Jun-88, Version 5 by Pitman
                  (fairly major overhaul, merging versions 3 and 4)
                21-Sep-88, Version 6 by Moon (stripped down)
		17-Oct-88, Version 7 by Loosemore (change direction again)
		30-Dec-88, Version 8 by Loosemore (tweaks)
		23-Jan-89, Version 9 by Loosemore (amendments)
		02-Mar-89, Version 10 by Loosemore (new proposal)
		11-Mar-89, Version 11 by Loosemore


Problem description:

 Common Lisp provides reader syntax (#,) which allows the programmer
 to designate that a particular expression within a program is to be
 evaluated early (at load time) but to later be treated as a constant.
 Unfortunately, no access to this capability is available to programs
 which construct other programs without going through the reader.
    
 Some computations can be deferred until load time by use of EVAL-WHEN,
 but since EVAL-WHEN must occur only at toplevel, and since the nesting
 behavior of EVAL-WHEN is quite unintuitive, EVAL-WHEN is not a general
 solution to the problem of load-time computation of program constants.

 Proposal R**2-NEW-SPECIAL-FORM was approved at the January 1989
 meeting.  After the meeting, some additional suggestions were made that
 have been incorporated into proposal R**3-NEW-SPECIAL-FORM.  The sections
 of the two proposals that differ are marked with change bars in the margin.
 
Proposal (LOAD-TIME-EVAL:R**2-NEW-SPECIAL-FORM):
    
 Add a new special form, LOAD-TIME-VALUE, which has the following
 contract:

   LOAD-TIME-VALUE form &optional read-only-p	[Special Form]

   LOAD-TIME-VALUE provides a mechanism for delaying evaluation of <form>
   until the expression is in the "runtime" environment.  

   If a LOAD-TIME-VALUE expression is seen by COMPILE-FILE, the compiler
|  performs normal semantic processing such as macro expansion but
|  arranges for the evaluation of <form> to occur at load time in a null
   lexical environment, with the result of this evaluation then being
   treated as an immediate quantity at run time.  It is guaranteed that 
   the evaluation of <form> will take place only once when the file is 
   loaded, but the order of evaluation with respect to the "evaluation" 
   of top-level forms in the file is unspecified.

   If a LOAD-TIME-VALUE expression appears within a function compiled
   with COMPILE, the <form> is evaluated at compile time in a null lexical
   environment.  The result of this compile-time evaluation is treated as 
   an immediate quantity in the compiled code.  

   In interpreted code, <form> is evaluated (by EVAL) in a null
   lexical environment, and one value is returned.  Implementations which
   implicitly compile (or partially compile) expressions passed to
   EVAL may evaluate the <form> only once, at the time this
   compilation is performed.  This is intentionally similar to the
   freedom which implementations are given for the time of expanding
   macros in interpreted code.

|  Note that, in interpreted code, there is no guarantee as to when
|  evaluation of <form> will take place, or the number of times the
|  evaluation will be performed.  Since successive evaluations of the
|  same LOAD-TIME-VALUE expression may or may not result in an evaluation
|  which returns a "fresh" object, destructive side-effects to the
|  resulting object may or may not persist from one evaluation to the
|  next.  It is safest to explicitly initialize the object returned by
|  LOAD-TIME-VALUE, if it is later modified destructively.
|   Implementations must guarantee that each reference to a
|  LOAD-TIME-VALUE expression results in at least one evaluation of its
|  nested <form>.  For example,
|    (DEFMACRO CONS-SELF (X)
|        `(CONS ,X ,X))
|    (CONS-SELF (LOAD-TIME-VALUE (COMPUTE-IT)))
|  must perform two calls to COMPUTE-IT; although there is only one
|  unique LOAD-TIME-VALUE expression, there are two distinct references
|  to it.
|
|  In the case of a LOAD-TIME-VALUE form appearing in a quoted expression 
|  passed to EVAL, each call to EVAL must result in a new evaluation of 
|  <form>.  For example,
|    (DEFVAR X 0)
|    (DEFUN FOO () (EVAL '(LOAD-TIME-VALUE (INCF X))))
|  is guaranteed to increment X each time FOO is called, while
|    (DEFUN FOO () (LOAD-TIME-VALUE (INCF X)))
|  may cause X to be evaluated only once.

   The READ-ONLY-P argument designates whether the result can be considered
   read-only constant. If NIL (the default), the result must be considered 
   ordinary, modifiable data. If T, the result is a read-only quantity
   which may, as appropriate, be copied into read-only space and/or shared
   with other programs. (Because this is a special form, this argument is
   -not- evaluated and only the literal symbols T and NIL are permitted.)


 Rationale:

   LOAD-TIME-VALUE is a special form rather than a function or macro 
   because it requires special handling by the compiler.

   Requiring the compiler to perform semantic processing such as macro
   expansion on the nested <form>, rather than delaying all such processing
   until load time, has the advantages that fewer macro libraries may need
   to be available at load time, and that loading may be faster and result
   in less consing due to macroexpansion.  If users really want to delay
   macroexpansion to load time, this can be done with an explicit call to
   EVAL, e.g.
  
    (LOAD-TIME-VALUE (EVAL '(MY-MACRO)))
    
   Allowing the same LOAD-TIME-VALUE to cause its nested <form> to be
   evaluated more than once makes simplifies its implementation in
   interpreters which do not perform a preprocessing code walk.  It also
   makes the rules for the time of its processing analogous to those
   for macro expansion.

   This proposal explicitly does -not- tie LOAD-TIME-VALUE to the #,
   read macro.  Doing so would be an incompatible change to the definition
   of #, (which is reliably useful only -inside- quoted structure,
   while LOAD-TIME-VALUE must appear -outside- quoted structure in a
   for-evaluation position).

   The requirement that LOAD-TIME-VALUE expressions be evaluated once per
   reference (rather than once per unique expression) prevents problems 
   that could result by performing destructive side-effects on a value 
   that is unexpectedly referenced in more than one place.


Proposal (LOAD-TIME-EVAL:R**3-NEW-SPECIAL-FORM):
    
 Add a new special form, LOAD-TIME-VALUE, which has the following
 contract:

   LOAD-TIME-VALUE form &optional read-only-p	[Special Form]

   LOAD-TIME-VALUE provides a mechanism for delaying evaluation of <form>
   until the expression is in the "runtime" environment.  

   If a LOAD-TIME-VALUE expression is seen by COMPILE-FILE, the compiler
|  performs its normal semantic processing (such as macro expansion and
|  translation into machine code) on the form, but arranges for the
|  execution of <form> to occur at load time in a null
   lexical environment, with the result of this evaluation then being
   treated as an immediate quantity at run time.  It is guaranteed that 
   the evaluation of <form> will take place only once when the file is 
   loaded, but the order of evaluation with respect to the "evaluation" 
   of top-level forms in the file is unspecified.

   If a LOAD-TIME-VALUE expression appears within a function compiled
   with COMPILE, the <form> is evaluated at compile time in a null lexical
   environment.  The result of this compile-time evaluation is treated as 
   an immediate quantity in the compiled code.  

   In interpreted code, <form> is evaluated (by EVAL) in a null
   lexical environment, and one value is returned.  Implementations which
   implicitly compile (or partially compile) expressions passed to
   EVAL may evaluate the <form> only once, at the time this
   compilation is performed.  This is intentionally similar to the
   freedom which implementations are given for the time of expanding
   macros in interpreted code.

|  If the same (compared with EQ) list (LOAD-TIME-VALUE <form>) is
|  evaluated or compiled more than once, it is unspecified whether <form>
|  is evaluated only once or is evaluated more than once.  This can
|  happen both when an expression being evaluated or compiled shares
|  substructure, and when the same expression is passed to EVAL or to
|  COMPILE multiple times.  Since a LOAD-TIME-VALUE expression may be
|  referenced in more than one place and may be evaluated multiple times
|  by the interpreter, it is unspecified whether each execution returns
|  a "fresh" object or returns the same object as some other execution.
|  Users must use caution when destructively modifying the resulting
|  object.
|
|  If two lists (LOAD-TIME-VALUE <form>) are EQUAL but not EQ, their
|  values always come from distinct evaluations of <form>.  Coalescing
|  of these forms is not permitted.

   The READ-ONLY-P argument designates whether the result can be considered
   read-only constant. If NIL (the default), the result must be considered 
   ordinary, modifiable data. If T, the result is a read-only quantity
   which may, as appropriate, be copied into read-only space and/or shared
   with other programs. (Because this is a special form, this argument is
   -not- evaluated and only the literal symbols T and NIL are permitted.)


 Rationale:

   LOAD-TIME-VALUE is a special form rather than a function or macro 
   because it requires special handling by the compiler.

   Requiring the compiler to perform semantic processing such as macro
   expansion on the nested <form>, rather than delaying all such processing
   until load time, has the advantages that fewer macro libraries may need
   to be available at load time, and that loading may be faster and result
   in less consing due to macroexpansion.  If users really want to delay
   macroexpansion to load time, this can be done with an explicit call to
   EVAL, e.g.
  
    (LOAD-TIME-VALUE (EVAL '(MY-MACRO)))
    
   Allowing the same LOAD-TIME-VALUE to cause its nested <form> to be
   evaluated more than once makes simplifies its implementation in
   interpreters which do not perform a preprocessing code walk.  It also
   makes the rules for the time of its processing analogous to those
   for macro expansion.

   This proposal explicitly does -not- tie LOAD-TIME-VALUE to the #,
   read macro.  Doing so would be an incompatible change to the definition
   of #, (which is reliably useful only -inside- quoted structure,
   while LOAD-TIME-VALUE must appear -outside- quoted structure in a
   for-evaluation position).

   Allowing multiple references to the same LOAD-TIME-VALUE expression
   to result in only one interpretation allows it to be specified more
   cleanly.  It also allows interpreters that do not perform a prepass
   to cache LOAD-TIME-VALUE expressions.


Current Practice:

   This is an addition to the language and has not yet been implemented.


Cost to Implementors:

   In compiled code, (LOAD-TIME-VALUE <form>) is similar to 
   '#,<form>.  Most implementations can probably make use of the same 
   mechanism they use to handle #, to handle LOAD-TIME-VALUE.  Note that
   #, does not currently provide a mechanism for dealing with 
   non-read-only-ness.

   Implementing LOAD-TIME-VALUE in the interpreter should be fairly
   straightforward, since one simply needs to evaluate the <form> in the
   null lexical environment.  Implementations that use a preprocessing
   code walk in the interpreter to perform macro expansion could process
   LOAD-TIME-VALUE forms at that time.

   Some code-walkers would have to be taught about this new
   special form. Such changes would likely be trivial.


Cost to Users:

   Some code-walkers would have to be taught about this new
   special form. Such changes would likely be trivial.


Benefits:

   Users are given a mechanism that to force evaluation to be delayed 
   until load time that does not rely on a feature of the reader.


Discussion:

   Earlier versions (up to version 7) of this proposal stated that
   all semantic processing of the LOAD-TIME-VALUE form should be postponed
   until load time.  

   The semantics of LOAD-TIME-VALUE would be simplified considerably if
   the READ-ONLY-P argument were removed and destructive operations on
   the result of evaluating <form> prohibited.  However, some people feel
   that the ability to destructively modify the value is an essential
   feature to include.

   "Collapsing" of multiple references to the same LOAD-TIME-VALUE 
   expression could be allowed for read-only situations, but it seems 
   like it would be more confusing to make it legal in some situations 
   and not in others.

   A number of other alternatives have been considered on this issue, 
   including:

   - A proposal for a new special form that would force evaluation of
     the <form> to happen only once.  This was rejected because of
     implementation difficulties.

   - A proposal to add a function making the "magic cookie" used by #,
     available to user code.  The current proposal does not prevent such
     a function from being added, but this approach appeared to have
     less support than making the hook available as a new special form.

   - A proposal to remove #, entirely (issue SHARP-COMMA-CONFUSION).

   - A suggestion to change the behavior of (EVAL-WHEN (LOAD) ...).


Kent Pitman says:
   Although I'm willing to take multiple evaluation in the interpreter
   as a compromise position, I would like it mentioned in the discussion
   that this was only an expedient to getting this issue accepted at all,
   and that I'm not really happy about it. I have said that I think a
   number of our lingering problems (with EVAL-WHEN, COMPILER-LET, and
   this -- for example) are due to the presence of interpreters which do
   not do a semantic-prepass at a known time. If I had my way, we would
   require a semantic pre-pass and we would then be able to forbid
   multiple evaluations even in the interpreter.

Moon and Gray support proposal R**3-NEW-SPECIAL-FORM.

Pitman also expressed willingness to go along with
R**3-NEW-SPECIAL-FORM, but was somewhat concerned that coalescing
LOAD-TIME-VALUE results based on EQ-ness of the LOAD-TIME-VALUE form
could conceivably lead to trouble down the line. However, since he
could provide no actual examples to back up that worry, and since the
majority opinion was that some implementations would find a
restriction against such coalescing an undue burden, the decision was
made to just `note the concern' and proceed on.  Sandra Loosemore and
JonL White concur with this position.

∂13-Mar-89  0853	X3J13-mailer 	issue COMPILER-VERBOSITY, version 6 
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 13 Mar 89  08:53:16 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Mon, 13 Mar 89 11:48:42 EST
Date: Mon, 13 Mar 89 11:50 EST
From: Barry Margolin <barmar@Think.COM>
Subject: issue COMPILER-VERBOSITY, version 6
To: cl-compiler@sail.stanford.edu
Cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131546.AA02078@defun.utah.edu>
Message-Id: <19890313165001.9.BARMAR@OCCAM.THINK.COM>

I see the benefit of :PRINT, but do we really need :VERBOSE?  What's the
difference between

	(compile path :verbose t)

and

	(format t "~&Compiling file ~A...~%" path)
	(compile-file path)
	(format t "~&done.~%")

If any users want to have this controlled by a global variable, they can
do what we (Thinking Machines) did years ago and package it up in their
own function.  At this stage of the game I don't see the need to add
gratuitous features like this.

:PRINT is less gratuitous because it implements a feature that the user
can't add himself.

                                                barmar

∂13-Mar-89  0855	X3J13-mailer 	Issue: UNSOLICITED-MESSAGES    
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 13 Mar 89  08:54:56 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 555652; Mon 13-Mar-89 11:51:33 EST
Date: Mon, 13 Mar 89 11:51 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: UNSOLICITED-MESSAGES
To: barmar@Think.COM
cc: KMP@STONY-BROOK.SCRC.Symbolics.COM, chapman%aitg.DEC@decwrl.dec.com,
    x3j13@sail.stanford.edu
In-Reply-To: <19890313163525.7.BARMAR@OCCAM.THINK.COM>
Message-ID: <890313115113.2.KMP@BOBOLINK.SCRC.Symbolics.COM>

    Date: Mon, 13 Mar 89 11:35 EST
    From: Barry Margolin <barmar@Think.COM>

	Date: Sun, 12 Mar 89 19:13 EST
	From: Kent M Pitman <KMP@stony-brook.scrc.symbolics.com>

	I agree that this is an important issue.
	I am not sure I agree with the proposed solution -- partly because
	I don't think it goes nearly far enough, and partly because I think the
	wording for the place where it stops encourages might actually encourage
	more `abuse' than currently exists.

	I think it should be possible to know with certainly that calling EQ,
	CONS, or even COMPILE, was not going to do I/O, at least in
	the normal case. 

    Do progress notes in the wholine count as output?  If not, why not?  ...

No. They are passive. The function in question does not output to the
wholine.  Rather, it arranges information such that a foreign process
can access it and display it. For example, if 500 calls to LOAD are done
in three second, you don't always get 500 progress messages. That is
because the output is done by the foreign process doing the polling and
not the process which is running the CL code. I think this distinction
is important. Indeed, if the running process could block, signal an
error, etc. due to problems in I/O then it would not be a good idea.

    If so, are you proposing that they be prohibited?

No.

    In Genera, calling
    COMPILE displays "Compiling <name>" in the wholine, and calling
    READ-CHAR on a console stream displays "User Input" in the wholine.

No. COMPILE does no display. A foreign process which is working by polling
does. This is no different than a foreign process doing any kind of 
debugging activity.

    I like these things, but I think it will be difficult to express this
    distinction in general enough terms in the standard.

I don't think it's that difficult.

			 In exceptional cases, CONS might produce GC warnings
	or COMPILE might produce compiler warnings, but never should COMPILE
	type out anything like 
	 Compiling FOO.
	or should EQ type out
	 Performing EQ comparison of #<FOO 32> and #<BAR 17>.
	Right now, nothing assures me of this and I find that disturbing.

    Why is this problem unique to Lisp?  Is there any wording in the C
    standard that explicitly prohibits malloc() from causing output?  I
    doubt it, yet I don't think they find this disturbing.

Maybe it's because C people have traditionally been willing to settle 
for less. :-) Seriously, I think it's a clear hole in their standard.
People would probably flame if things that weren't documented as doing
I/O were to suddenly start doing it.

    I think market forces should be enough to prevent really silly
    unsolicited messages,

Really I don't. COMPILE is a notable offender. Real implementations have
been known to print "Compiling FOO." on *TERMINAL-IO* and this proposal
does not forbid it.

In some cases, market pressure can --- after some number of months --
get things back in line. In others, implementors just point to the standard
and either say "it doesn't say anything" or even worse suggest that the
reason it doesn't say it is because it wants to leave room.

Not all implementors come from our culture. Often, those that don't
would -prefer- to have little `hints' (rules?) like this specified so
that the process of making incidental decisions would be easier. For
example, it's not unreasonable that implementors find themselves asking
"Should COMPILE say something?" -- It's been traditional for compilers
in languages where you couldn't invoke the compiler at runtime to do
typeout, so they might naturally assume that the same should be true
here. Certainly it's natural for them to at least answer the question.

    just as all serious Lisp implementations have a GC
    even though CLtL never mentions it.

This comes up because it's a "hard issue" and new implementors naturally
tend to discuss "hard issues" with other implementors before even getting
started. My guess is that no new implementor would consider calling up
Moon or JonL or Masinter to ask what the I/O behavior of COMPILE should
be. Probably they would just make a guess, hope it was right, and move on
to the next seemingly trivial decision.

∂13-Mar-89  0853	X3J13-mailer 	issue MACRO-CACHING, version 2 
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  08:49:54 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA19529; Mon, 13 Mar 89 09:47:42 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02151; Mon, 13 Mar 89 09:47:38 -0700
Date: Mon, 13 Mar 89 09:47:38 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131647.AA02151@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue MACRO-CACHING, version 2

Issue:        MACRO-CACHING
Forum:	      Compiler
References:   8.2 Macro Expansion (CLtL pp151-152),
	      Issues PACKAGE-CLUTTER, LISP-SYMBOL-REDEFINITION, 
 	      QUOTE-SEMANTICS (a.k.a. QUOTE-MAY-COPY),
	      and MACRO-ENVIRONMENT-EXTENT
Category:     Clarification
Edit history: 31-Jan-89, Version 1 by Pitman
	      11-Mar-89, Version 2 by Loosemore (add discussion)
Status:	      Ready for release

Background:

  CLtL suggests that macro caching is a legitimate strategy.

  Two particular kinds of caching are common:

   Displacement. A macro expansion function displaces the actual macro in
    order to avoid any later need for lookup.

   Table. A macro expression is looked up in a cache (such as a hash table)
    to avoid having to run the expander code.

  While CLtL seems to expressly suggest these strategies to be legitimate,
  linguistic constraints show that in most cases they are not. The problems
  are things like:

    - lexical scoping (MACROLET and SYMBOL-MACROLET, and FLET and LET to
	the extent that they shadow the effect of MACROLET and SYMBOL-MACROLET,
	respectively).

    - ``read only'' structure
  
  To see the problem, consider the following examples:

   (SETQ FOO1 '(FOO))

   (EVAL `(LIST (MACROLET ((FOO (&WHOLE FORM) '(+ 1 1))) ,FOO1)
	        (MACROLET ((FOO (&WHOLE FORM) '(+ 1 2))) ,FOO1)))
   => (2 3)

  Note that because the lexical contour may vary for an EQL expression,
  however, displacing the expansion will cause confusion:

   (DEFUN DISPLACE (X Y)
     (SETF (CAR X) (CAR Y))
     (SETF (CDR X) (CDR Y))
     X)

   (DEFVAR FOO2 '(FOO))

   (EVAL `(LIST (MACROLET ((FOO (&WHOLE FORM)
		 	     (DISPLACE FORM '(+ 1 1)))) ,FOO2)
	        (MACROLET ((FOO (&WHOLE FORM)
			     (DISPLACE FORM '(+ 1 2)))) ,FOO2)))
   => (2 2)

  CLtL suggests that a displacement hook might be placed in
  *MACROEXPANSION-HOOK*. The above example shows that to be an
  unreliable technique.

  If this were not enough, displacement is also inappropriate because
  no Common Lisp primitive can tell the difference between regular list
  structure and read-only list structure. Since a macro form being
  expanded might have been read-only in some implementations (e.g., EVAL
  of a quoted list), the macro cannot reliably side-effect the structure.

  In the case of table-lookup, the problem is more complicated. 
  Table-lookup does not have a necessary effect beyond the particular
  lookup being done at the moment. To do table-lookup correctly relies
  on the key being not only the expression but also the lexical 
  environment object. Whether the cost of making and throwing away so
  many tables was worth the savings over running the macro expander is
  not at all clear. And the GC effects of caching every macro environment
  ever seen may be extraordinary, however correctness could in principle
  be preserved by doing such a two-dimensional lookup... at least unless
  we decide that macro environments have only dynamic extent. [A separate
  proposal, MACRO-ENVIRONMENT-EXTENT, addresses this issue. If it passed,
  then there would really be no way for users to do reliable macro caching
  without cooperation from the system to have the cache be part of the
  environment itself.]

Problem Description:

  Macro caching by displacement is provably not semantically valid.

  Macro caching by table lookup is difficult for a user to do correctly,
  and in any case is not possible to handle efficiently in user code.

Proposal (MACRO-CACHING:DISALLOW):

  1. a. Clarify that macro caching by displacement is not semantically
        valid in user code.

     b. Clarify that macro caching by displacement is semantically valid
        for system macros and special forms, provided that such caching
        does not prejudice the expansion of user-code contained in any
        displaced code. For example:
         (PROG () (FOO))
        could displace to a BLOCK, but the (FOO) must appear un-expanded
        in the BLOCK in case the BLOCK occurs in more than one lexical
	environment.

  2. a. Clarify that macro caching by table lookup is not semantically
	valid in user code in order to correctly respect the lexical
        environment.

	Implementations are free to extend the language to permit such
	lookup and to offer functions which support it in a more efficient
	way, but code using such functions would, of course, not be portable.

     b. Clarify that macro caching by table lookup is valid for the system,
        but only if it correctly respects the lexical environment.

Proposal (MACRO-CACHING:RESTRICT):

  Like DISALLOW, but change 2a to:

	Clarify that macro caching by table lookup is semantically valid only
	if the lookup is keyed both on the form and the environment.
     
	Implementations are free to extend the language to offer functions
	which support it in a more efficient way, but code using such functions
	would, of course, not be portable.

Rationale:

 1. a. Displacement has effects which by their nature transcend
       lexical boundaries.

    b. The system can assure that lexical boundaries are irrelevant in some
       cases because users are not permitted to redefine or shadow definitions
       in the initial LISP system. [See issues PACKAGE-CLUTTER and 
       LISP-SYMBOL-REDEFINITION.]

 2. a. Users can only associate an environment with a macro cache table
       in a very clumsy way. Also, Permitting them to do so at all forces
       macro environments to have indefinite extent, and works against
       efficiency in compilers.

    b. The system is capable of allocating space in an environment object
       for a macro cache which can be reliably kept up in synch with the
       lexical environment environment.

Test Case:

 ;; #1: File compiling this definition in some implementations will produce
 ;;     a definition that returns read-only list structure. The call to EVAL
 ;;     on the result must not try to modify the read-only structure during
 ;;     macroexpansion. [See issue QUOTE-SEMANTICS.]

 (DEFUN READ-ONLY-FOO () '(MACROLET ((FOO (&WHOLE FORM) (+ 1 1))) (FOO)))

 (EVAL (READ-ONLY-FOO))
 => 2

 ;; #2: This constructs a form and then uses it in two places in another
 ;;     constructed form. Each of the uses is in a different lexical
 ;;     contour, so must be expanded differently.

 (LET ((FOO (LIST 'FOO)))
   (EVAL `(LIST (MACROLET ((FOO (&WHOLE FORM) '(+ 1 1))) ,FOO)
		(MACROLET ((FOO (&WHOLE FORM) '(+ 1 2))) ,FOO))))
 => (2 3)  

 ;; #3: This is effectively the same thing but involves a MACROLET
 ;;     shadowing a DEFMACRO rather than two MACROLETs, since some
 ;;     implementations might only be caching expansions that come
 ;;     from DEFMACRO.

 (DEFMACRO FOO (&WHOLE FORM) '(+ 1 1))

 (LET ((FOO (LIST 'FOO)))
   (EVAL `(LIST ,FOO (MACROLET ((FOO (&WHOLE FORM) '(+ 1 2))) ,FOO))))
 => (2 3)

Current Practice:

 Symbolics Genera does not use displacing or table caching in either
 the interpreter or compiler.

 Symbolics Cloe, a compiled only implementation, uses table caching
 to boost compilation by a little. Running the test cases above turned
 up a bug (in test case #3), which is now in the process of being fixed.
 [The fact that a bug was turned up in code written by a CL implementor
  is an existence proof that the potential for trouble was not imagined.]

 Both Symbolics Cloe and Symbolics Genera support *MACROEXPANSION-HOOK*,
 leaving open the possibility of users bringing disasters upon themselves.

 Macro environment objects in Symbolics Genera are stack-allocated, so 
 have only dynamic extent.

Cost to Implementors:

 This proposal is upward compatible with correct implementations.

Cost to Users:

 There is no cost to users of the RESTRICT proposal, unless they were doing
 semantically invalid caching.

 The cost to users of the DISALLOW proposal is a loss of speed in some cases
 which are semantically valid. In general, however, the efficiency and 
 usefulness of such caching is subject to question in code intended to be
 ported. Given that implementations are not required to ever give the same
 environment object twice, the caching may be all for naught in some
 implementations.

Cost of Non-Adoption:

 Continued widespread confusion about whether displacement is a legitimate
 implementation technique for user code.

Benefits:

 Since *MACROEXPANSION-HOOK* is in the Lisp package, multiple applications
 in the same environment share its effects. Often one application will
 clobber another's hook, or introduce a hook that is not desirable to other
 applications when none previously existed. Since a common use of
 *MACROEXPANSION-HOOK* is to install a macro caching mechanism, clarifying
 the situations in which *MACROEXPANSION-HOOK* should not be used will
 decrease the likelihood of one program breaking, slowing down, or otherwise
 adversely affecting another.

Aesthetics:

 Most people agree that macro caching techniques are only supposed to improve
 speed without affecting semantics. This proposal is only intended to
 underscore that necessary truth. Insofar as this is only a clarification,
 it presumably has no significant aesthetic impact.

Discussion:

 Pitman thinks it's a good idea to clarify this issue because it's not really
 spelled out now and it's the sort of thing programmers can waste a lot of
 time bickering about to no good end. Either the functionality is reliable
 and should be encouraged, or it is not reliable and should be discouraged
 or forbidden. Pitman supports the DISALLOW proposal because it leaves open
 the possibility of making macro environments have dynamic extent, but he
 can live with the RESTRICT position, which he believes represents the
 status quo.

 Bob Laddaga (a Cloe maintainer who reviewed a draft of this proposal) 
 supports the DISALLOW option as well.

 David Grays says:
  I can accept MACRO-CACHING:DISALLOW.

  The Explorer evaluator does displacement of macros, but is careful to
  correctly handle the cases exemplified in your test cases #1 and #2.  
  It does not do the right thing for #3, but that is a bug that can fairly
  easily be fixed.

 Sandra Loosemore says:
  This issue is closely tied to MACRO-ENVIRONMENT-EXTENT.  If we decide
  environments have (or can be made to have) indefinite extent, I see no
  reason not to go with MACRO-CACHING:RESTRICT.  On the other hand, if
  we decide environments have only dynamic extent, proposal
  MACRO-CACHING:DISALLOW is the only one that makes sense.

∂13-Mar-89  0924	X3J13-mailer 	issue QUOTE-SEMANTICS, version 2    
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  09:23:57 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA20995; Mon, 13 Mar 89 10:21:38 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02184; Mon, 13 Mar 89 10:21:33 -0700
Date: Mon, 13 Mar 89 10:21:33 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131721.AA02184@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue QUOTE-SEMANTICS, version 2

This issue replaces QUOTE-MAY-COPY, which was distributed and discussed
briefly at the last meeting.

Forum:		Compiler
Issue:		QUOTE-SEMANTICS
Subsumes:	Issue QUOTE-MAY-COPY
References:	CLtL p. 55, 78, 86, 143
		Issue CONSTANT-COLLAPSING
		Issue CONSTANT-COMPILABLE-TYPES
		Issue CONSTANT-CIRCULAR-COMPILATION
Category:	CLARIFICATION
Edit History:   V1, 22 Jan 1989, Sandra Loosemore
		V2, 13 Mar 1989, Sandra Loosemore (discussion)
Status:		Ready for release


Problem Description:

Is it permissible for COMPILE and EVAL to coalesce or copy constants?
Are there constraints upon what kinds of objects may appear as
constants in code processed by COMPILE or EVAL, similar to those for
COMPILE-FILE?

CLtL p86 states that (QUOTE <x>) simply returns <x>.  On p55 it is
mentioned that the only self-evaluating forms that may be copied are
numbers or characters.  It is also stated that an implementation is
permitted to collapse (or coalesce) EQUAL constants "appearing in code
to be compiled" (p78), which is defined to mean self-evaluating forms
or objects contained in a QUOTE form (without reference to whether the
form is processed by EVAL, COMPILE, or COMPILE-FILE).

Because of its nature as a file processor, COMPILE-FILE generally must
cause copies of constants to be constructed when the compiled code is
loaded.  In a number of existing Lisp implementations, COMPILE also
causes constant objects to be copied and/or coalesced.  There is also
at least one implementation where constants are copied by EVAL in some
circumstances.


Proposal QUOTE-SEMANTICS:NO-COPYING:

State that copying or coalescing of constants appearing in code
processed by EVAL and COMPILE is not permitted; the resulting program
must reference objects that are EQL to the corresponding objects in
the source code.  The constraints on what kinds of objects may appear
as constants (described in issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION) apply only to COMPILE-FILE.

  Rationale:

  This proposal is consistent with what many people think of as the
  "traditional" semantics for QUOTE.  It gives users maximum flexibility
  about what kinds of objects may appear as constants.
   


Proposal QUOTE-SEMANTICS:COPYING-ALLOWED-BUT-NO-CONSTRAINTS:

State that copying or coalescing of constants appearing in code
processed by EVAL and COMPILE is permitted.  Copying or coalescing may
only take place when the source code is "promoted" to being a program
by EVAL or COMPILE, not at runtime.  Function definitions are promoted
to being a program when the form enclosing the definition (e.g., a
FUNCTION or DEFUN form) is promoted.

Any object may validly appear as a constant in code processed by EVAL
or COMPILE.  The constraints on what kinds of objects may appear as
constants (described in issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION) apply only to COMPILE-FILE.

  Rationale:

  This proposal is the most consistent with the semantics stated in CLtL.
  It gives users maximum flexibility about what kinds of objects may
  appear as constants.


Proposal QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE:

State that copying or coalescing of constants appearing in code
processed by EVAL and COMPILE is permitted.  Copying or coalescing may
only take place when the source code is "promoted" to being a program
by EVAL or COMPILE, not at runtime.  Function definitions are promoted
to being a program when the form enclosing the definition (e.g., a
FUNCTION or DEFUN form) is promoted.

The constraints on what kinds of objects may appear as constants
(described in issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION) apply to EVAL and COMPILE as well as to
COMPILE-FILE.

  Rationale:

  This makes the rules for handling of constants consistent between
  EVAL, COMPILE, and COMPILE-FILE.  It gives implementors maximum 
  flexibility in handling constants in EVAL and COMPILE.


Current Practice:

Implementations in which COMPILE attempts to copy all constants
include PSL/PCLS and Kyoto Common Lisp.  

In Lucid Common Lisp, constants are not normally copied by COMPILE,
but since COMPILE does coalesce constants, it may cause QUOTE to
return an object which is not EQL to the object which appeared in the
source code.

Symbolics Genera has COMPILE copy list, string, non-displaced array,
and (I-Machine only) closure constants, but Moon says he thinks this
is wrong.

There is known to be at least one implementation where expanding the
DEFUN macro causes all constants in the body of the function to be
copied.


Cost to implementors:

Proposal NO-COPYING would involve a significant cost in those
implementations where constants are now copied or coalesced by EVAL
and COMPILE.  Some implementations would also require substantial
changes to support proposal COPYING-ALLOWED-BUT-NO-CONSTRAINTS.  The
aspect that is likely to cause the most problems is that, in some
implementations, the garbage collector assumes that constants
referenced in compiled code have been copied to read-only storage and
do not need to be scanned or relocated.

Proposal SAME-AS-COMPILE-FILE has no adoption cost above what is
required to support issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION.


Cost to users:

Proposals COPYING-ALLOWED-BUT-NO-CONSTRAINTS and SAME-AS-COMPILE-FILE
may break some existing programs that assume constants in code
processed by EVAL or COMPILE are always EQL to the corresponding
objects in the source code.  Proposal SAME-AS-COMPILE-FILE may also
break existing programs that depend on referencing "undumpable"
constants in code processed by EVAL or COMPILE.  In both cases,
however, the behavior is already nonportable.  Both proposals would
permit implementations in which these programs now work to continue to
provide their existing behavior.


Benefits:

The semantics of QUOTE are clarified.


Discussion:

This issue subsumes issue QUOTE-MAY-COPY, which caused a very lengthy
debate on the cl-compiler mailing list.

This issue relates to conformance requirements.  Accepting either of
proposals NO-COPYING or COPYING-ALLOWED-BUT-NO-CONSTRAINTS would mean
that not all conforming programs could be compiled with COMPILE-FILE.
Some people may find this disturbing, particularly since one of the
goals of Common Lisp has been to try to eliminate differences in
semantics between compiled and interpreted code.

Loosemore supports proposal QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE,
since it requires essentially no conversion cost for implementors and
does not break any user programs that are not already nonportable.

JonL White says:
  Since we have already passed the proposal that permits constants to 
  be "read-only" -- it is an error to modify them -- and have already 
  passed  the proposal that allows access to updateable structures -- 
  LOAD-TIME-EVAL -- then there is no excuse for being overly concerned
  with the storage address of quoted data.  People who have mistakenly 
  used structured constants as updatable data should convert over to 
  either LOAD-TIME-EVAL or DEFPARAMETER.

Kent Pitman says:
  The problem is that a lot of copying advocates have been going around
  trying to use "the need for copying" as leverage for restricting
  the set of things which I may quote. My view is that it is my write [sic]
  to quote whatever I want, and it's up to the person who thinks they
  can do something fun with copying to not get themselves in deeper than
  they can handle.

Jeff Dalton says: 
  I would agree [with Pitman's remarks] too.  My only quibble is that
  it's not just "the need for copying" that's used a lever.
  "Consistency with file compilation" is also being used as a lever.

∂13-Mar-89  0929	X3J13-mailer 	issue SAFE-CODE, version 1
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  09:29:10 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA21179; Mon, 13 Mar 89 10:26:59 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02193; Mon, 13 Mar 89 10:26:56 -0700
Date: Mon, 13 Mar 89 10:26:56 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903131726.AA02193@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue SAFE-CODE, version 1

Issue:        SAFE-CODE
Forum:	      Compiler
References:   OPTIMIZE declaration (p160),
	      Issue ERROR-TERMINOLOGY
Category:     CLARIFICATION/CHANGE
Edit history: 07-Mar-89, Version 1 by Pitman
Status:	      Ready for release

Problem Description:

  The new error terminology refers to ``safe code'' in the definition
  of the term and CLtL refers to 
  individual meanings of OPTIMIZE qualities, but there is no standardized
  way of relating the two concepts.

Proposal (SAFE-CODE:SAFETY-3):

  Define that, formally, the term ``safe code'' is code refers to any
  code in which the OPTIMIZE quality for SAFETY has a value of 3.

  Implementors might wish to consider treating other situations as safe
  as well, but in making that decision both the relative values of other
  OPTIMIZE qualities and the idiosyncratic properties of the particular
  implementation should also be taken into account.

Examples:

  1. The body of the following is safe...

     a. (LOCALLY (DECLARE (OPTIMIZE (SAFETY 3))) . body)
     b. (LOCALLY (DECLARE (OPTIMIZE SAFETY    )) . body)

  2. The body in each of the following is unsafe. They might
     or might not be treated as safe, possibly depending
     on the values of other qualities and specifics of the
     implementation.

     a. (LOCALLY (DECLARE (OPTIMIZE (SAFETY 0))) . body)
     b. (LOCALLY (DECLARE (OPTIMIZE (SAFETY 1))) . body)
     c. (LOCALLY (DECLARE (OPTIMIZE (SAFETY 2))) . body)


Rationale:

  Programmers will probably intuitively expect that the term 
  ``highest safety'' refers to giving the SAFETY quality its
  highest safety.

Current Practice:

  Implementors ...

    Symbolics Genera does error checking always, and ignores OPTIMIZE
    declarations.
  
    Symbolics Cloe heeds OPTIMIZE declarations, but effectively makes
    `judgment calls' in every case because there is no clear guidance
    on how to interpret them.

  Programmers ...

    Many programmers write (DECLARE (SPEED 0) (SAFETY 3)) even when all
    they really want to control is SAFETY because they are afraid that
    unless they explicitly sacrifice speed, the compiler will ignore
    their plea for error checking.

Cost to Implementors:

  Some implementations might require a lot of nitpicky little changes.

Cost to Users:

  Technically none.  No portable code can really rely on much of any
  reliable effect out of any of the OPTIMIZE qualities. However, some
  users may rely on implementation-specific features of implementations,
  and if those implementations are forced to change, non-portable user
  code might break in some ways.

Cost of Non-Adoption:

  The meaning of ``safe code'' will not be clearly defined.

Benefits:

  Programmers will be able to say what they mean. They can stop
  superstitiously putting (SPEED 0) next to (SAFETY 3) just to
  assure they get safe code.

Aesthetics:

  Improved. This will make the English align well with the code.

Discussion:

  It is very important that we reach consensus in some form on this issue.

  Pitman supports SAFE-CODE:SAFETY-3.

∂13-Mar-89  1014	X3J13-mailer 	Issue: UNSOLICITED-MESSAGES    
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 13 Mar 89  10:14:33 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Mon, 13 Mar 89 13:09:40 EST
Date: Mon, 13 Mar 89 13:10 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Issue: UNSOLICITED-MESSAGES
To: Kent M Pitman <KMP@stony-brook.scrc.symbolics.com>
Cc: chapman%aitg.DEC@decwrl.dec.com, x3j13@sail.stanford.edu
In-Reply-To: <890313115113.2.KMP@BOBOLINK.SCRC.Symbolics.COM>
Message-Id: <19890313181059.0.BARMAR@OCCAM.THINK.COM>

    Date: Mon, 13 Mar 89 11:51 EST
    From: Kent M Pitman <KMP@stony-brook.scrc.symbolics.com>

	Date: Mon, 13 Mar 89 11:35 EST
	From: Barry Margolin <barmar@Think.COM>

	Do progress notes in the wholine count as output?  If not, why not?  ...

    No. They are passive. The function in question does not output to the
    wholine.  Rather, it arranges information such that a foreign process
    can access it and display it. For example, if 500 calls to LOAD are done
    in three second, you don't always get 500 progress messages. That is
    because the output is done by the foreign process doing the polling and
    not the process which is running the CL code. I think this distinction
    is important. Indeed, if the running process could block, signal an
    error, etc. due to problems in I/O then it would not be a good idea.

So, the acceptability of progress notes has nothing to do with the
stream they are displayed on, only the fact that they are displayed by a
background process?  This implies that a single-tasking machine that
displayed progress notes synchronously would therefore be unacceptable.
I find this distinction extremely arbitrary, since it is based only on
the implementation, not the program-visible effects.

	I like these things, but I think it will be difficult to express this
	distinction in general enough terms in the standard.

    I don't think it's that difficult.

We'll have to come up with a general definition of passive output versus
active output.  And we'll still have to make sure that passive output
isn't allowed to go to *STANDARD-OUPTUT*.

	Why is this problem unique to Lisp?  Is there any wording in the C
	standard that explicitly prohibits malloc() from causing output?  I
	doubt it, yet I don't think they find this disturbing.

    Maybe it's because C people have traditionally been willing to settle 
    for less. :-) Seriously, I think it's a clear hole in their standard.
    People would probably flame if things that weren't documented as doing
    I/O were to suddenly start doing it.

Actually, I think the difference is that Common Lisp includes some
operations that are not traditionally included in runtime libraries,
COMPILE, COMPILE-FILE, and LOAD being the most notable ones.  No
Lisp implementor would even think of having CONS or EQ produce output,
just as the C standard doesn't need to say that malloc() is silent.

Perhaps this means that since we have such unusual runtime facilities,
we can't rely on common sense as other languages do.  I would be willing
to support a blanket statement that said that no output may be produced
by functions other than that specified in the standard or due to the
signalling of conditions detected by the function.

Would this prevent an implementation from having a *DEBUG-CONS* variable
that turns on debugging output by CONS?

                                                barmar

∂13-Mar-89  1046	X3J13-mailer 	Issue: UNSOLICITED-MESSAGES    
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 13 Mar 89  10:46:36 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 555842; Mon 13-Mar-89 13:43:40 EST
Date: Mon, 13 Mar 89 13:43 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: UNSOLICITED-MESSAGES
To: x3j13@sail.stanford.edu
cc: barmar@Think.COM, KMP@STONY-BROOK.SCRC.Symbolics.COM,
    chapman%aitg.DEC@decwrl.dec.com
In-Reply-To: <890313115113.2.KMP@BOBOLINK.SCRC.Symbolics.COM>
Message-ID: <890313134321.9.KMP@BOBOLINK.SCRC.Symbolics.COM>

[Further discussion on this topic will take place on CL-Editorial.]

∂13-Mar-89  1450	X3J13-mailer 	**DRAFT** issue CLOS-MACRO-COMPILATION, version 2  
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  14:50:22 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA07805; Mon, 13 Mar 89 15:48:10 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02496; Mon, 13 Mar 89 15:48:08 -0700
Date: Mon, 13 Mar 89 15:48:08 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903132248.AA02496@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: **DRAFT** issue CLOS-MACRO-COMPILATION, version 2

This issue is still under discussion.  There has been a lot of talk
about how this relates to the creation of meta-objects at compile
time, but the only proposals that have been made so far are the two
included here.

Forum:		Compiler
Issue:		CLOS-MACRO-COMPILATION
References:	CLOS chapters 1 & 2 (88-002R)
		CLOS chapter 3 (89-003)
		Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
		Issue DEFINING-MACROS-NON-TOP-LEVEL
Category:	CLARIFICATION
Edit History:   V1, 10 Mar 1989, Sandra Loosemore
		V2, 13 Mar 1989, Sandra Loosemore
Status:		**DRAFT**


Problem Description:

Do the CLOS defining macros (DEFCLASS, DEFMETHOD, DEFGENERIC, and
DEFINE-METHOD-COMBINATION) have compile-time side-effects similar
to those for DEFSTRUCT or DEFMACRO?

A part of the problem is that we do not currently have a full
understanding of all the issues involved.  In particular, work on
defining the CLOS meta-object protocol is still in progress.  The goal
of this proposal is to say enough about the behavior of these macros
in the standard so that users can use them portably in compiled code,
but to leave as much of the behavior as possible unspecified to avoid
placing undue restrictions on the meta-object protocol.

There are two proposals, MINIMAL and NOT-SO-MINIMAL.


Proposal CLOS-MACRO-COMPILATION:MINIMAL:

 State that top-level calls to the CLOS defining macros have the
 following compile-time side-effects.  Any other compile-time behavior
 is explicitly left unspecified.

  DEFCLASS:
  
  * The class name becomes a type specifier which may appear in 
    subsequent type declarations.
  
  * The class name can be used to name a superclass in a subsequent
    DEFCLASS.
  
  * The class name can be used as a specializer in a subsequent 
    DEFMETHOD.
  
  DEFGENERIC:
  
  * The generic function can be referenced in a subsequent DEFMETHOD.  

  * The generic function is not callable at compile-time.
  
  DEFMETHOD:
  
  * The method is not callable at compile-time.  If there is a generic
    function with the same name at compile-time, compiling a DEFMETHOD
    will not add the method to that generic function.  The compiler may
    perform tests for lambda-list congruence only between the DEFGENERICs
    and DEFMETHODs for a given generic function name that appear within
    the file being compiled, and not against a generic function of the 
    same name which exists in the compile-time environment.
  
  DEFINE-METHOD-COMBINATION:
  
  * The method combination can be used in a subsequent DEFGENERIC.  If it
    is referenced, the body of a long form of method combination must be 
    evaluable at compile-time.

 Rationale:

  The compile-time behavior of DEFCLASS is similar to DEFSTRUCT or
  DEFTYPE.  

  DEFGENERIC and DEFMETHOD are similar to DEFUN, which doesn't add the
  function definition to the compile-time environment.  Since generic
  functions may be freely redefined between compile and run time (just
  like any other function), a method may end up "belonging" to a
  different generic function at load time than at compile time.

  Some implementations compose effective methods at compile time, which
  requires evaluating the body of the DEFINE-METHOD-COMBINATION at
  compile time.


Proposal CLOS-MACRO-COMPILATION:NOT-SO-MINIMAL:

 This is the same as proposal MINIMAL, except under DEFCLASS add:

  * The class may be instantiated at compile-time.  Provided the 
    appropriate methods are also defined at compile-time, this implies:
    - The class can be used as the :METACLASS option of a later DEFCLASS.
    - It can be used as the :GENERIC-FUNCTION-CLASS or :METHOD-CLASS option
      of a DEFGENERIC, GENERIC-FUNCTION, GENERIC-FLET, or GENERIC-LABELS.

 Rationale:

  Being able to instantiate a class at compile-time is somewhat more 
  convenient for users.


Current Practice:

  The items listed under DEFCLASS in proposal MINIMAL are fairly standard
  programming style.

  Flavors does not support compile-time instantiation of classes.  It
  does not make method combinations available at compile-time either, but
  Moon considers that to be a bad design choice.

Cost to implementors:

  Unknown.

Cost to users:

  Unknown, but probably fairly small.

  Note that for proposal NOT-SO-MINIMAL, users still have to ensure that
  any methods on the class which may be invoked at compile-time are 
  fully defined.  This includes the INITIALIZE-INSTANCE and 
  SHARED-INITIALIZE methods that are invoked by MAKE-INSTANCE.

  Wrapping an (EVAL-WHEN (EVAL COMPILE LOAD) ...) around the appropriate
  definitions will make sure they are fully defined at compile-time.
  Alternatively, the definitions could be placed in a separate file,
  which is loaded before compiling the file that depends on those
  definitions.

Benefits:

  Programmers can rely on programs that use the CLOS defining macros 
  being able to compile correctly in all implementations, without having
  to wrap explicit EVAL-WHENs around every macro call.

Discussion:

  This writeup is based on discussions between Moon, Gray, and
  Loosemore, who are mostly in agreement on the things presented in
  proposal MINIMAL.  We have purposely avoided saying anything about
  whether meta-objects representing the classes, methods, etc. get
  created at compile-time, or whether such meta-objects are fully or
  partially defined.  The basic questions addressed by this issue are
  what kinds of things can be defined and then used during compilation
  of the same file that defines them, and what restrictions might apply.

  These proposals are not completely compatible with the meta-object 
  protocol document (89-003).  Gregor Kiczales says:
    No one believes that what is written in draft 10 of the MOP is valid.

  Sandra Loosemore says:
    Although I admit I don't understand all of the issues involved with
    the meta-object protocol, I prefer proposal MINIMAL over 
    NOT-SO-MINIMAL.  I don't think leaving the issue of whether or not
    classes can be instantiated at compile-time unspecified places an
    undue burden on users, and it does leave more freedom for the
    meta-object protocol to decide what the right behavior really is.

  Dick Gabriel notes:
    The question I have about the process going on with respect to the
    CLOS-MACRO-COMPILATION issue is whether the fine-grained behavior of
    CLOS under various compilation/evaluation situations is being
    over-specified. 

    At this stage of the game I worry that we might go a little too far in
    one direction in specification when we are actually engaged in design
    work. This isn't intended to be a criticism of any committees, but I
    would feel a lot more comfortable with a conservative specification
    that defined well-formed programs being loaded or compiled in fresh
    Common Lisps with a pretty simple eval-when model that is easier to
    specify and which makes it easy for all but the hairiest
    compilation-environment-frobbing programs to be written.





∂13-Mar-89  1452	X3J13-mailer 	issue COMPILE-ENVIRONMENT-CONSISTENCY, version 4   
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  14:52:29 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA07899; Mon, 13 Mar 89 15:50:10 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02499; Mon, 13 Mar 89 15:50:07 -0700
Date: Mon, 13 Mar 89 15:50:07 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903132250.AA02499@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue COMPILE-ENVIRONMENT-CONSISTENCY, version 4

Forum:		Compiler
Issue:		COMPILE-ENVIRONMENT-CONSISTENCY
References:	CLtL p. 68-69, 143, 321
		RAM's "Compiler Cleanup Proposal #3"
Category:	CLARIFICATION
Edit History:   V1, 2 Sep 1988, Sandra Loosemore (initial draft)
		V2, 9 Sep 1988, Sandra Loosemore (incorporate suggestions)
		V3, 26 Oct 1988, Sandra Loosemore (add suggestion from Benson)
		V4, 08 Mar 1989, Sandra Loosemore (wording changes)


Problem Description:

CLtL does not clearly specify what aspects of the compiletime
environment the compiler (or other preprocessor) may "wire in" to code
being compiled.  At what time (compiletime or runtime) are certain
kinds of definitions "captured"?  What happens if these definitions
are not consistent at both compile and run times?


Proposal COMPILE-ENVIRONMENT-CONSISTENCY:CLARIFY:

The process of compilation causes certain kinds of information present
in the compiletime environment to be captured and incorporated into
the resulting compiled code.  Other kinds of information may not be
captured until the compiled code is actually run.  

Specifically:

(1) The following information *must* be present in the compiletime
environment for the program to be compiled correctly.  This
information need not also be present in the runtime environment.

    (a) In conforming code, macros referenced in the code being compiled
        must have been previously defined in the compiletime environment.
	The compiler must treat any form that is a list beginning with
	a symbol that does not name a macro or special form as a function
	call.  (This implies that SETF methods must also be available at
	compiletime.)

    (b) In conforming code, variables that are intended to be bound
        specially must be declared SPECIAL in the compiletime environment
        before any bindings of that variable are processed by the compiler.
	The compiler must treat any binding of an undeclared variable as a
	lexical binding.


(2) The compiler *may* incorporate the following kinds of information
into the code it produces, if the information is present in the
compiletime environment and is referenced within the code being
compiled.  Except where some other behavior is explicitly stated, when
the compiletime and runtime definitions are different, it is
unspecified which will prevail within the compiled code.  In all
cases, the absence of the information at compiletime is not an error,
but its presence may enable the compiler to generate more efficient
code. 

    (a) The compiler may assume that functions that are defined and
	declared INLINE in the compiletime environment will retain the
        same definitions at runtime.

    (b) The compiler may assume that, within a named function, a
	recursive call to a function of the same name refers to the
	same function, unless that function has been declared NOTINLINE.

    (c) COMPILE-FILE may assume that, in the absence of NOTINLINE
	declarations, a call within the file being compiled to a named
	function which is defined in that file refers to that function.
	(This permits "block compilation" of files.)  The behavior of
	the program is unspecified if functions are redefined individually 
	at runtime.

    (d) The compiler may assume that the signature (or "contract") of
	all built-in Common Lisp functions will not change.  In addition,
	the compiler may treat all built-in Common Lisp functions as if
	they had been proclaimed INLINE.

    (e) The compiler may assume that the signature (or "contract") of
	functions with FTYPE information available will not change.  (See
	issue FUNCTION-TYPE-ARGUMENT-TYPE-SEMANTICS.)

    (f) The compiler may "wire in" the values of symbolic constants
	that have been defined with DEFCONSTANT in the compiletime
	environment.

    (g) The compiler can assume that type definitions made with DEFTYPE 
        or DEFSTRUCT in the compiletime environment will retain the same 
        definition in the runtime environment.  It may also assume that
        a class defined by DEFCLASS in the compiletime environment will
        be defined in the runtime environment in such a way as to have
        the same superclasses and metaclass.  This implies that
        subtype/supertype relationships of type specifiers will not 
        change between compiletime and runtime.  (Note that it is not 
        an error for an	unknown type to appear in a declaration at
        compiletime, although it is reasonable for the compiler to 
        emit a warning in such a case.)

    (h) The compiler may assume that if type declarations are present
	in the compiletime environment, the corresponding variables and 
	functions present in the runtime environment will actually be of
	those types; otherwise, the runtime behavior of the program is 
	undefined.


(3) The compiler *must not* make any additional assumptions about
consistency between the compiletime and runtime environments.  In 
particular:

    (a) The compiler may not assume that functions that are defined
	in the compiletime environment will retain the either the
	same definition or the same signature at runtime, except
	in situations (2a) through (2e) above.  It is, however,
	permissible for the compiler to emit warning messages when
        compiling calls to functions that are defined in the compiletime
        environment, but where the wrong number or type of arguments
        are supplied.

    (b) The compiler may not signal an error if it sees a call to a
	function that is not defined at compiletime, since that function
	may be provided at runtime.  Again, it is permissible for the
        compiler to emit a warning in these situations.

	

Rationale:

This proposal generally reflects current practice.


Current Practice:

There don't seem to be any compilers around that do not implement the
provisions of item (1).

For item (2), most compilers (including Lucid) optimize self-recursive
calls by default.  Most compilers also opencode data structure
accessors (such as CAR) at some level of optimization, and some code
much more complicated built-in functions inline as well.  VaxLisp, for
example, normally compiles MEMBER inline.  The Lucid compiler makes
use of type declarations to perform generic-to-specific
transformations on many arithmetic and sequence functions, which is
also a form of inlining.  KCL performs block compilation by default,
and Lucid does so under certain conditions.


Cost to implementors:

Unknown, but probably minor.


Cost to users:

Since most implementations appear to be largely in conformance with the
proposal, users should notice little difference.


Benefits:

The presence of a definite specification of what may happen when will
help users structure their programs so they will compile correctly in
all Common Lisp implementations.


Discussion:

Most of the discussion on this issue has been centered on the
terminology describing error situations for item (2).  In most cases
where there is an inconsistency between compile-time and run-time, the
results will be unpredictable but harmless.  The major exception is
violation of type declarations, which is a "crash-and-burn" error in
many implementations.

There has also been some concern raised that item (3) would prohibit
such things as a cross-compiler that produces standalone programs in
an environment that disallows redefinition of functions.  The intent
of this proposal is not to prohibit a compiler from having a magic
switch that imposes additional restrictions on the programs it
compiles, but such a compiler would not be a compiler for Common Lisp.

Several people have expressed reservations about items 2b and 2c, saying
that self-tail-recursion optimization and block compilation should not
be the default behavior of the compiler.  Gail Zacharias responds:

  This item [2c] has nothing to do with whether anybody does it by
  default.  The question is whether an end user can take a Common Lisp
  program whose internals he's not familiar with, block-compile it, and
  be guaranteed that it will continue to function correctly.  This item
  says that yes, a correct CL program must explicitly indicate what
  functions in the source it will redefine at runtime.  I don't think
  this places such a great burden on the programmer.  Without this
  provision, only somebody intimately familiar with a program could know
  whether it can be safely block-compiled, making block-compilation
  useless in the context of portable CL programs.
  
  This thing about "block compilation shouldn't be the default" seems to
  come up every time this item is discussed.  That's an environment
  question and is not addressed by the proposal.  The proposal simply
  says that block compilation should be legal.

∂13-Mar-89  1514	X3J13-mailer 	issue COMPILE-FILE-SYMBOL-HANDLING, version 2 
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  15:14:36 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA08718; Mon, 13 Mar 89 16:12:23 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02542; Mon, 13 Mar 89 16:12:19 -0700
Date: Mon, 13 Mar 89 16:12:19 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903132312.AA02542@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue COMPILE-FILE-SYMBOL-HANDLING, version 2

Forum:		Compiler
Issue:		COMPILE-FILE-SYMBOL-HANDLING
References:	CLtL p. 182
		Issue IN-PACKAGE-FUNCTIONALITY
		Issue CONSTANT-COMPILABLE-TYPES
		Issue DEFPACKAGE (passed)
Category:	CHANGE/CLARIFICATION 
Edit History:   V1, 01 Feb 1989, Sandra Loosemore
		V2, 12 Mar 1989, Sandra Loosemore (discussion, error terms)
Status:		Ready for release


Problem Description:

It is not clear how COMPILE-FILE is supposed to specify to LOAD how
symbols in the compiled file should be interned.  In particular, what
happens if the value of *PACKAGE* is different at load-time than it
was at compile-time, or if any of the packages referenced in the file
are defined differently?

There are three proposals:  CURRENT-PACKAGE, HOME-PACKAGE, and
REQUIRE-CONSISTENCY.


Proposal COMPILE-FILE-SYMBOL-HANDLING:CURRENT-PACKAGE:

  When a compiled file is loaded, the interned symbols it references
  are found by the following procedure.  The rules are applied in the
  order listed and only the first applicable rule has any effect.

  (1) Any symbol accessible at compile time in the package that is the
      value of *PACKAGE* is found by calling INTERN at load time with one
      argument, the name of the symbol.

  (2) A keyword symbol is found by finding or creating a keyword symbol
      with the same name.
    
  (3) A symbol that at compile time is an external symbol of its home
      package is found at load time by finding the package with the same
      name as the compile-time home package, and then finding an exported
      symbol of that package with the same name as the compile-time symbol.
      If no such package exists, no such symbol exists, or the symbol is not
      exported, an error is signalled.

  (4) Any other symbol is found by calling INTERN at load time with two
      arguments, the name of the symbol and the package with the same name
      as the compile-time symbol's home package.  If no such package exists,
      an error is signalled.

  The goal of this procedure is for each symbol reference to be
  resolved to the same symbol when a compiled file is loaded as when
  the source file is loaded directly with LOAD.  It is possible to
  create package structures that make that impossible; for example, it
  is possible for a symbol to be inaccessible from its own home
  package.  A conforming program cannot depend on any symbol
  resolution behavior that is not provided by the above four rules.
  
  If any top level form in a compiled file changes the value of
  *PACKAGE*, other than a SELECT-PACKAGE appearing as the first
  top level form in the file, the package in which the loader will
  place the constant symbols referenced in the file is unspecified.


  Rationale:

    Proposal CURRENT-PACKAGE makes COMPILE-FILE/LOAD follow the same
    rules as PRINT/READ.  For any symbol not written with a package
    prefix in the source file (which should be the great majority of
    them), CURRENT-PACKAGE will make loading the compiled file get the
    same symbols as loading the source file.

    The reason for the rule about changing the value of *PACKAGE* is that
    many loaders cache the interning of symbols; if the same symbol 
    appears multiple times in the source file, its name may only be 
    looked up once at load time.  Since not all loaders are required to
    work this way, changing *PACKAGE* in mid-file is not allowed,
    because the effect on later occurrrences of a symbol would be
    implementation-dependent.


Proposal COMPILE-FILE-SYMBOL-HANDLING:HOME-PACKAGE:

  When a compiled file is loaded, the interned symbols it references are
  found by calling INTERN at load time with two arguments, the name of
  the symbol and the package with the same name as the compile-time
  symbol's home package.  If no such package exists, an error is
  signalled. 
  
  The goal of this procedure is for each symbol reference to be resolved
  to the same symbol when a compiled file is loaded as when the source
  file was processed by COMPILE-FILE.  A conforming program cannot
  depend on any symbol resolution behavior that is not provided by the
  above rule.

  If any top level form in a compiled file changes the value of
  *PACKAGE* when the file is loaded interpretively but not during
  compile-time processing by COMPILE-FILE, the package in which the
  loader will place the constant symbols referenced in the file is
  unspecified.
 
  Rationale:

    The behavior specified in this proposal is simple and easy to 
    understand (there is only one rule to remember instead of four).  
    It does not require any restrictions on where top-level
    SELECT-PACKAGE forms may appear in the file.  It allows a compiled
    file that does not include an explicit SELECT-PACKAGE to be loaded 
    successfully no matter what the load-time value of *PACKAGE* is,
    as long as the compile-time value of *PACKAGE* was the "right" 
    package.


Proposal COMPILE-FILE-SYMBOL-HANDLING:REQUIRE-CONSISTENCY:

  In order to guarantee that compiled files can be loaded correctly,
  users must ensure that the packages referenced in the file are defined
  consistently at compile and load time.  Conforming Common Lisp programs
  must satisfy the following requirements:
  
  (1) The value of *PACKAGE* when the contents of the file are compiled 
      by COMPILE-FILE must be the same as the value of *PACKAGE* when
      the file is loaded.  In particular:

      (a) If any top level form in a compiled file changes the value
          of *PACKAGE*, other than a SELECT-PACKAGE appearing as the first 
          top-level form in the file, the package in which the loader
          will place the constant symbols referenced in the file is
          unspecified.

      (b) If the first top-level form in the file is not a call to
          SELECT-PACKAGE, then the value of *PACKAGE* at the time LOAD is
          called must be a package with the same name as the package that
          was the value of *PACKAGE* at the time COMPILE-FILE was called.

  (2) For all symbols that were accessible in *PACKAGE* at compile
      time but whose home package was another package, at load time there
      must be a symbol with the same name that is accessible in both the
      load-time *PACKAGE* and in the package with the same name as the
      compile-time home package.
  
  (3) For all symbols in the compiled file that were external symbols in
      their home package at compile time, there must be a symbol with the
      same name that is an external symbol in the package with the same name
      at load time.
        
  If any of these conditions do not hold, the package in which LOAD looks
  for the affected symbols is unspecified.  Implementations are permitted 
  to signal an error or otherwise define this behavior.
  
  Otherwise, when a compiled file is loaded, the interned symbols it
  references are found by calling INTERN at load time with two
  arguments, the name of the symbol and the package with the same name
  as the compile-time symbol's home package.  If no such package exists,
  an error is signalled.

  Rationale:

    Any program that behaves differently under the other two proposals
    is already nonportable.  This proposal is merely an explicit 
    statement of the status quo, namely that users cannot depend on
    any particular behavior if the package environment at load time is
    inconsistent with what existed at compile time.


Current Practice:

  PSL/PCLS implements something very similar to proposal HOME-PACKAGE,
  as does A-Lisp.  Utah Common Lisp implements something like proposal
  CURRENT-PACKAGE, but the chief compiler hacker says he thinks that
  proposal HOME-PACKAGE actually makes more sense, and agrees that any
  program that behaves differently under the two proposals is broken.

  The TI Explorer currently implements proposal HOME-PACKAGE, after
  trying it both ways.
  
  KCL implements something like HOME-PACKAGE (symbols in the compiled
  file are explicitly qualified with the name of their home package),
  except that it differentiates between internal and external symbols.
  
  Lucid Lisp appears to implement something like proposal CURRENT-PACKAGE.

  Symbolics Genera implements CURRENT-PACKAGE.  Symbolics Cloe probably
  does also.
  
  Coral also implements something like proposal CURRENT-PACKAGE.
  
  
Cost to implementors:

  Proposals HOME-PACKAGE and CURRENT-PACKAGE would be incompatible
  changes for implementations that currently do things the other way.
  It would probably be easier to convert to HOME-PACKAGE than
  CURRENT-PACKAGE, since it is less complicated.
  
  Proposal REQUIRE-CONSISTENCY is intended to be compatible with either
  of the other two proposals, but it may not be entirely compatible with
  the details of current implementations.


Cost to users:

  Proposal HOME-PACKAGE places the fewest restrictions on user programs.
  
  Proposal CURRENT-PACKAGE places a restriction on where and how the value
  of *PACKAGE* may be changed within the file.  
  
  Proposal REQUIRE-CONSISTENCY places even more restrictions on user
  programs.
  
  Most of these restrictions are probably already necessary in portable
  programs.  However, some nonportable programs that depend on the "other"
  model may be broken by proposals HOME-PACKAGE or CURRENT-PACKAGE.
  
  For a discussion of how these proposals treat nonportable or erroneous
  programs, see the "Analysis" section below.
  
  
Benefits:

  COMPILE-FILE's treatment of symbols is made explicit in the standard.
  
  
Analysis:

  Proposals CURRENT-PACKAGE and HOME-PACKAGE present two different
  models of how this problem might be solved.  Essentially, proposal
  CURRENT-PACKAGE uses the same rules as PRINT/READ in deciding when to
  qualify symbols with a package name and where to find unqualified
  symbols.  Proposal HOME-PACKAGE requires -all- symbols written to the
  compiled file to be qualified with an explicit package, and the loader
  simply INTERNs the symbol names in that package.
  
  These two proposals differ in the following situations.  Proposal
  REQUIRE-CONSISTENCY, in effect, says that valid programs do not cause
  any of these situations to occur, and the behavior in such cases is
  unspecified (allowing both models to be used as valid implementation
  techniques).
  
  (1) The situation where the file does not contain a SELECT-PACKAGE
      and where the compile-time value of *PACKAGE* is a package with a
      different name than the load-time value of *PACKAGE*.
      
      Proposal CURRENT-PACKAGE would intern the names of symbols that 
      were accessible in *PACKAGE* at compile time in *PACKAGE* at load time.
      
      Proposal HOME-PACKAGE would intern the names of symbols that
      were accessible in *PACKAGE* at compile time in the package with
      the same name as their compile-time home package.
      
      In general, programs must be compiled in the "right" package, so
      that the compiler can find and apply the correct macro expansions,
      type definitions, and so on; see issue COMPILE-ENVIRONMENT-CONSISTENCY.
      As a result of macroexpansion or other transformations applied by
      the compiler, the compiled file may contain symbol references that
      were not present in the source file.  Proposal CURRENT-PACKAGE may
      cause problems because these references may be resolved to be
      symbols other than the ones that were intended.  Since proposal
      HOME-PACKAGE remembers the home package of all symbols, it is much
      more likely to find the correct symbols at load time.
          
  (2) The situation where *PACKAGE* is altered by a top-level form
      that is not a SELECT-PACKAGE which is the first top-level form in
      the file.
      
      Proposal CURRENT-PACKAGE says this is illegal.  This is because
      of the difficulty in deciding what the "current package" is, if it
      is allowed to change throughout the file.
      
      Proposal HOME-PACKAGE says this is OK, as long as *PACKAGE* is
      altered in the same way at compile time as when the file is loaded
      interpretively.  This is possible because the behavior this
      proposal specifies does not depend on what the value of *PACKAGE*
      is once symbols in the source file have been read by COMPILE-FILE.
      
      Some people argue that allowing *PACKAGE* to be switched in
      mid-file is a bad idea anyway; it is not really necessary and it
      implies a restriction on COMPILE-FILE to read forms from the file 
      one at a time, processing each form before the next call to READ.
      
      Others argue that restricting SELECT-PACKAGE to be the first
      top-level form is an artificial contrivance.  The compile-time
      behavior of SELECT-PACKAGE is well-defined no matter where it
      appears in the file.  There is also a problem defining what "the
      first top-level form" really means.  Finally, this model requires 
      all package definitions to be made externally to the file, which 
      may be inconvenient for smaller programs that now contain the 
      package definition and package contents all in one file.

  (3) The situation where there is a symbol accessible in the
      compile-time value of *PACKAGE* but with another home package, and
      where at load time there is not a symbol with the same name that
      is accessible in both packages.  This situation might occur, for
      example, if at compile time there is a symbol that is external in
      its home package and that package is used by *PACKAGE*, but where
      there is no such external symbol in that package at load time, or
      the load-time *PACKAGE* does not use the other package.
      
      Proposal CURRENT-PACKAGE would find or create a symbol accessible
      in *PACKAGE*.
      
      Proposal HOME-PACKAGE would find or create a symbol accessible in
      a package with the same name as the symbol's compile-time home
      package.
      
      Some people feel that the behavior of proposal CURRENT-PACKAGE is
      more intuitive in this situation, and that it is more forgiving of
      differences between the compile-time and load-time package
      structures.  Others feel that the behavior of HOME-PACKAGE is more
      intuitive, and that if there have been significant changes to the
      package structures, it is probably an indication that the file
      needs to be recompiled anyway, since the compiler might have
      picked up macro definitions and the like from the wrong package.
  
  (4) The situation where a symbol is external in its home package
      and where there is no such external symbol in that package at load
      time.
      
      Proposal CURRENT-PACKAGE would quietly find or create the symbol
      in *PACKAGE* if the symbol were accessible in *PACKAGE* at compile
      time.  Otherwise, it will signal an error.
      
      Proposal HOME-PACKAGE would always just quietly find or create the 
      symbol as internal in its home package.
      
      Not complaining when a symbol that is supposed to be external
      isn't can be seen as a violation of modularity.  However, it seems
      like this argument should apply equally to symbols whose home
      package is *PACKAGE* as symbols whose home package is somewhere
      else.
          

Discussion:

  Loosemore is opposed to proposal CURRENT-PACKAGE, but would be
  less opposed to it if it contained an explicit statement that
  *PACKAGE* must be a package with the same name at load time as at
  compile time.  She thinks proposal HOME-PACKAGE is the best of the
  options presented here.
  
  Moon is opposed to proposal HOME-PACKAGE, but would be less
  opposed to it if it required an error to be signalled when a
  symbol that was external at compile time is not external at load
  time.  He thinks proposal CURRENT-PACKAGE is the best of the options
  presented here.

  John Kolts, who did the implementation on the TI Explorer, recalls:

    My primary motivation was compile/load consistency.  I thought it was
    important that during loading all symbol references should resolve to
    the same symbol as they would have during the compilation.  If, for
    instance, the packages used by *package* were different at compile
    time than at load time, my approach would still intern the accessible
    symbols in the "right" package during loading.  [...]  Of course, such
    an approach means that loading the [compiled file] could give results
    incompatible with loading the LISP file directly, but I felt that if
    behavior consistent with some altered package structure was desired,
    the file should be recompiled, a relatively small price to pay for the
    benefit of this consistency.
    
    A related consideration was that remembering the home package seemed to
    be important for proper macro expansion in certain cases.
    
    What was apparent was that there were several defensible approaches,
    none of which was obviously the absolutely right way to handle certain
    pathological situations.  Making the expected behavior explicit in a
    standard is a good idea.

  David Gray says:

    There really shouldn't be anything wrong about using SELECT-PACKAGE
    multiple times within a file as long as it is used at top level so
    that the compiler knows that the current package is being changed.

  Cris Perdue says:

    [Proposal HOME-PACKAGE] doesn't ensure that the home package remains
    the same across compilation and loading, which I consider the key
    consideration.  How about this statement instead?

    "When a file is compiled, the symbol name is recorded together
    with the home package name and an indication of whether the
    symbol is external in its home package.  At load time the
    symbol is effectively looked up with:

    (find-symbol string (find-package pkg-name))

    If the symbol is noted as external, it must be found at load
    time as :external.  If it is noted as internal, it must either
    be present in the package or not found at all.  If it is not found
    at all, it is created as if by:

    (intern string (find-package pkg-name))

    If the package system is not in a suitable state, an error is
    signalled."

    This is what I consider "the right thing".

  JonL White says:

    I don't believe we have anything to gain at this point in trying to
    standardize the faslout package-qualification algorithm; this is
    notwithstanding that standardizing PRINT output, as an interchange
    format, is an absolute requirement [even though READ-of-PRINT will
    likely be even more information losing than loading in a compiled
    file!]

∂13-Mar-89  1517	X3J13-mailer 	issue COMPILER-LET-CONFUSION, version 7  
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  15:16:50 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA08737; Mon, 13 Mar 89 16:14:30 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02546; Mon, 13 Mar 89 16:14:26 -0700
Date: Mon, 13 Mar 89 16:14:26 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903132314.AA02546@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue COMPILER-LET-CONFUSION, version 7

Issue:		COMPILER-LET-CONFUSION
Forum:	        Compiler
References:	CLtL p. 112
Category:	CHANGE
Edit History:   V1, 27 Sep 1988, Sandra Loosemore (initial version)
                V2, 04 Oct 1988, Sandra Loosemore (add another example)
		V3, 31 Oct 1988, Sandra Loosemore (only proposal ELIMINATE)
	        V4, 08 Jan 1989, Kent M. Pitman (new alternative)
		V5, 09 Jan 1989, Sandra Loosemore (discussion)
		V6, 08 Mar 1989, Sandra Loosemore (general updating)
		V7, 13 Mar 1989, Sandra Loosemore (fix bug from V6)

Problem Description:

 The description of the COMPILER-LET special form in CLtL is confusing
 to many people.  There are no examples provided to make it clear how it
 is supposed to be used. The only description which is offered is overly
 concrete, which has led to confusion about the intent of COMPILER-LET,
 and about its implementability.
 
 The intent of COMPILER-LET was to permit information to be communicated
 between macros by use of dynamic variables at macroexpansion time.
 It was not necessary to the intended uses of COMPILER-LET that such
 variables ever be bound at execution time.  
 
 Unfortunately, probably because some implementations did not primitively
 support COMPILER-LET at the time CLtL was written, an exception was 
 permitted to make COMPILER-LET `more or less work' in interpreters: 
 the COMPILER-LET variables were permitted to be bound at execution time.
 The problem was further compounded by the fact that CLtL presented this
 exception as part of COMPILER-LET's contract rather than as an 
 implementation note, and by the fact that no examples of actually using
 COMPILER-LET correctly are provided.

 One particular case where problems have resulted is a situation like
   (compiler-let ((*v* 1))
     #'(lambda () (m)))
 where M is a macro that refers to *V*.  In some implementations, M is
 not macroexpanded until the dynamic extent of the *V* binding has
 ended.
 
 Subtle bugs can be introduced because of the different handling of the
 variable bindings in the interpreter and the compiler.  In compiled
 code, the bindings are only lexically visible during the expansion of
 macros at compile time, while in interpreted code the bindings have
 dynamic scope and may also be seen during ordinary evaluation if
 evaluation and macroexpansion happen "in parallel".
 
 Further compatibility problems can result from the value forms being
 evaluated in a null lexical environment in the compiler and the ordinary
 lexical environment in the interpreter.
 
Background and Analysis:

 It should be clear up front that COMPILER-LET is not computationally
 essential. Most (if not all) uses of it can be rewritten using MACROLET
 or SYMBOL-MACROLET.

 A typical use of COMPILER-LET might be:

  (defvar *local-type-declarations* '())
     
  (defmacro local-type-declare (declarations &body forms)
    `(compiler-let ((*local-type-declarations* 
		      (append ',declarations *local-type-declarations*)))
       ,@forms))
     
  (defmacro typed-var (var)
    (let ((type (assoc var *local-type-declarations*)))
      (if type `(the ,(cadr type) ,var) var)))
     
  (defun f (x y)
    (local-type-declare ((x fixnum) (y float))
      (+ (typed-var x) (typed-var y))))
    

 The same thing could be accomplished using MACROLET:
  
  (defmacro local-type-declare (declarations &body forms)
    (local-type-declare-aux declarations forms))
    
  (defmacro typed-var (var) var)

  (eval-when (eval compile load)
    (defun local-type-declare-aux (declarations forms)
      `(macrolet ((typed-var (var)
		    (let ((type  (assoc var ',declarations)))
		      (if type `(the ,(cadr type) ,var) var)))
		  (local-type-declare (new-declarations &body new-forms)
		    (local-type-declare-aux
		      (append new-declarations ',declarations)
		      new-forms)))
	 ,@forms)))


 A further alternative would be to use SYMBOL-MACROLET (this particular
 implementation assumes that issue DEFINING-MACROS-NON-TOP-LEVEL passes):

  (let ((temp  (gensym)))
    (defmacro local-type-declare (declarations &body forms &environment env)
      `(symbol-macrolet ((,temp  ',(append declarations
					  (symbol-macro-value temp env))))
         ,@forms))
    (defmacro typed-var (var &environment env)
      (let ((type  (assoc var (symbol-macro-value temp env))))
	(if type `(the ,(cadr type) ,var) var)))
    )
			  
  (defun symbol-macro-value (symbol env &optional default)
    (multiple-value-bind (expansion macro-p) (macroexpand symbol env)
      (if macro-p (eval expansion) default)))

 
 Opinion is divided as to which is more understandable.  Some
 people find the COMPILER-LET idiom more understandable (assuming that
 it can be made to work consistently in compiled and interpreted
 code), while others find it just as natural to use MACROLET or 
 SYMBOL-MACROLET.

 The issues are these:

  - Is it possible to implement COMPILER-LET in a usefully consistent
    way in all implementations?

  - Are the benefits of providing a useful and compatible implementation
    of COMPILER-LET worth any associated cost?

 Two proposals are presented below:

  - Option REPAIR argues that COMPILER-LET provides interesting
    functionality that can be implemented in a manner that is usefully
    consistent across implementations, and that the associated cost
    is low enough for it to be worthwhile to do so.

  - Option ELIMINATE argues that COMPILER-LET complicates the language
    and that providing this construct is not worth the associated 
    implementation cost.


Proposal (COMPILER-LET-CONFUSION:REPAIR):

  Strike the existing definition of COMPILER-LET. Redefine it as follows:
  
  COMPILER-LET						  [Special form]
  
    COMPILER-LET is similar to LET, but it always makes special 
    bindings and makes those bindings visible only during 
    macroexpansion of forms in the body, not during the runtime
    execution of those forms. 

    The intent is that some macros might macroexpand into calls to
    COMPILER-LET in which the body would the contain references to
    macros which access the variables in the COMPILER-LET.
  
    The initial value forms of the bindings, if any, are always 
    evaluated in a null lexical context, regardless of whether the
    COMPILER-LET expression is being interpreted or compiled.
  
    The initial value forms of the bindings, if any, are evaluated in
    a dynamic context where the bindings of any lexically enclosing
    COMPILER-LET are visible, and where dynamic execution-time 
    environment may or may not be visible.
  
    Implementation Note: Permitting the execution-time dynamic
    environment to be visible when initializing COMPILER-LET variables
    is a concession to some interpreters which may have to do this in
    order to keep the cost down. Where feasible, implementors should
    try not to make the runtime environment visible.

  Rationale:

    This gives a consistent description of COMPILER-LET which separates
    issues of intent from those of implementation in a way that makes it
    possible for portable code to make serious use of it, and which does
    not force gratuitous incompatibilities between interpreters and
    compilers.

    This description of COMPILER-LET can be implemented without undue
    cost by all implementations. See "Cost to Implementors" for details.

  Cost to Implementors:

    Modest, but nontrivial in some implementations.

    In compiled code, and in interpreters doing a one-time semantic
    prepass, it should be fairly easy for COMPILER-LET to cause the 
    variables to get bound (using PROGV) during semantic analysis.

    In interpreters which do not do a semantic-prepass, it is necessary
    to fully macroexpand the body. Assuming the presence of a
    SYSTEM::MACROEXPAND-ALL primitive, the definition of COMPILER-LET
    could look like:
      (DEFMACRO COMPILER-LET (BINDINGS &BODY FORMS &ENVIRONMENT ENV)
        (SETQ BINDINGS ;; Assure no non-atom bindings
	      (MAPCAR #'(LAMBDA (BINDING) 
		          (IF (ATOM BINDING) (LIST BINDING) BINDING))
		      BINDINGS))
        (PROGV (MAPCAR #'CAR BINDINGS)
	       (MAPCAR #'CDR BINDINGS)
	  (SYSTEM::MACROEXPAND-ALL `(PROGN ,@FORMS) ENV)))
    This reduces the problem of writing a program capable of doing a
    full macroexpansion. Many systems already have such a facility.
    Pitman wrote such a facility in Cloe Runtime in order support 
    SYMBOL-MACROLET (before it was christened a special form); it was
    about 750 lines of relatively straightforward, well-commented code.

  Cost to Users:

    Code currently depending on this feature is either non-existent or
    already not portable (due to wide variation in implementation 
    strategy for COMPILER-LET).

    Most users will probably be happy for any interpretation which offers
    them a future shot at portability.

    Some users have indicated they dislike interpreters which do a semantic
    prepass, because they like to be able to dynamically redefine macros
    while debugging.


Proposal (COMPILER-LET-CONFUSION:ELIMINATE):

  Remove COMPILER-LET from the language.
  
  Rationale:

    Some people think that having one less special form would simplify the
    language.  The revised COMPILER-LET semantics, which require
    COMPILER-LET to make special bindings which are only visible during
    expansion of macros which appear lexically within its body, are
    not shared by any other feature in the language, and require a
    fairly complex implementation technique.  There are other
    constructs which are strictly lexical that can be readily used
    to solve the same kinds of problems that COMPILER-LET is intended to
    be used for.

  Cost to Implementors:
  
    Minimal.  Implementations could continue to support COMPILER-LET as
    an extension.
  
  Cost to Users:
  
    Code currently depending on this feature is either non-existent or
    already not portable (due to wide variation in implementation 
    strategy for COMPILER-LET).

    People who use COMPILER-LET would have to rewrite their programs to use
    some other construct.  As discussed above, most uses of COMPILER-LET
    for communication between macros can be handled using MACROLET or
    SYMBOL-MACROLET, though some perspicuity may be lost in the process.


Current Practice:
  
 Some implementations have implemented the description in CLtL. 
 Users of those implementations (quite reasonably) can't figure how to 
 use COMPILER-LET and so don't use it much.

 Some implementations (the ones from which COMPILER-LET originally came)
 continue to use their pre-CLtL semantics. These semantics are useful, though
 incompatible with CLtL (which they largely consider to simply be in error).
 Users of those implementations probably use COMPILER-LET somewhat more 
 often since it has an intelligible behavior, but their code is not portable
 since it relies on behaviors which are either contrary to or not guaranteed
 by CLtL.

Benefits:

 Either way, a potential area of incompatibility between compiled and
 interpreted code would be eliminated.

 Either way, a potential area of portability trouble would be very
 drastically reduced (in the case of the REPAIR option) or eliminated
 (in the case of the ELIMINATE option).

Discussion:

 Pitman strongly favors COMPILER-LET-CONFUSION:REPAIR.  He argues 
 against the idea of using MACROLET instead of COMPILER-LET, saying:

  This is a little misleading because it's like saying you can
  do without LET given that you have FLET. You can, but you lose some things
  in the process:
 
  Just as rewriting a LET using FLET might slow your computation, so too
  a rewrite of COMPILER-LET using MACROLET might slow things down. However,
  compilation speed is generally not weighted as heavily as execution speed
  by many people, so the loss of speed here may not be as important.
 
  Just as rewriting a LET using FLET might obscure the simplicity of your
  intent, so too rewriting COMPILER-LET using MACROLET might obscure your
  intent. You'd probably get used to recognizing idioms if you used it often
  enough. Certainly this would be true if you didn't have LET. However,
  COMPILER-LET is used less often, so not having it would mean that the
  code you wrote instead would be much harder to read because people
  wouldn't have the necessary familiarity with the idioms involved and so
  wouldn't always understand them.
 
 Sandra Loosemore responds:

  The argument that using MACROLET is more inefficient than COMPILER-LET
  is questionable.  Both of the suggested implementation techniques for
  COMPILER-LET involve considerable overhead.

  If COMPILER-LET were not part of the language, people wouldn't think in
  terms of rewriting COMPILER-LETs as MACROLETs; instead, they'd think of
  how to use MACROLET in the first place to solve their problems.  This
  is what people who now use implementations with broken COMPILER-LETs
  already do.  Since MACROLET is now used much more frequently than
  COMPILER-LET, that argues that people are much more familiar with 
  MACROLET idioms than COMPILER-LET idioms.

  Also, note that the intent of the revised COMPILER-LET definition is
  to make the binding only lexically visible within the body.  Using
  special binding for this purpose is troublesome.  Both the MACROLET
  and SYMBOL-MACROLET solutions are completely lexical and avoid all
  the problems associated with special binding.

Glenn Burke thinks it needs to be emphasized that the code-walker
mentioned in the REPAIR proposal does not need to be portable.  He
says:

  The present wording makes it sound like a piece of cake to do with
  portable code, when the reality is that a good fraction of CL cleanup
  effort has involved the lack of capability of producing such a beast.
  Without one or more of a number of proposals being accepted, a fully
  correct portable code walker cannot be built, in my belief.

  I object to the flippant attitude of just "presupposing" this
  "trivial" function which "we know how to do".

∂13-Mar-89  1531	X3J13-mailer 	**DRAFT** issue DEFCONSTANT-NOT-WIRED, version 6   
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  15:30:56 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA09104; Mon, 13 Mar 89 16:28:40 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02557; Mon, 13 Mar 89 16:28:37 -0700
Date: Mon, 13 Mar 89 16:28:37 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903132328.AA02557@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: **DRAFT** issue DEFCONSTANT-NOT-WIRED, version 6

We don't expect to ask for a vote on this issue -- the writeup is just
being distributed so that we can refer to it in case the issue ever
comes up again.  None of the suggestions listed here seemed to have a
great deal of support among people on the cl-compiler list, and all of
them have problems we haven't been able to resolve yet.

Forum:		Compiler
Issue:		DEFCONSTANT-NOT-WIRED
References:     CLtL pages 68-69
                COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS,
               	PROCLAIM-LEXICAL,
                DECLARE-TYPE-FREE,
                DEFCONSTANT-SPECIAL
Category:       ADDITION
Edit history:   09 Oct 1988, V1 by David Gray
		27 Oct 1988, V2 by David Gray (new proposal)
                10 Nov 1988, V3 by David Gray - updated proposal, rationale
		  and discussion sections in response to comments.
                21 Nov 1988, V4 by David Gray - SPECIAL cancels CONSTANT;
		  CONSTANT doesn't require previous SPECIAL.
                28 Nov 1988, V5 by Sandra Loosemore (clean up, fix
		  some consistency problems)
                13 Mar 1989, V6 by Sandra Loosemore (start over)
Status:		**DRAFT**


Problem description:

  DEFCONSTANT performs two different functions:

    - It says that it is an error to SETQ or rebind the variable which
      is being defined as a constant.

    - It gives the compiler permission to evaluate the initial value form
      at compile time, and to build assumptions about the value into
      programs being compiled.

  In some cases, one would like to have the first behavior without
  getting the second.  In particular, one would like to get the same
  behavior with regard to signalling errors and warnings that you get
  with DEFCONSTANT.

  Common Lisp provides no mechanism for specifying a variable should
  be treated in this way.


Proposal DEFCONSTANT-NOT-WIRED:FIX-DEFPARAMETER:

  This is what DEFPARAMETER was supposed to be used for.  The description
  of DEFPARAMETER needs to be clarified to reflect this, perhaps by
  saying that a continuable error should be signalled if an attempt is
  made to SETQ or rebind a variable defined with DEFPARAMETER.

  Rationale:
    DEFPARAMETER apparently derives from Zetalisp's DEFCONST construct,
    which was used to indicate that values that would "never" change,
    without licensing the compiler to make assumptions about that value.
    However, most uses of DEFCONST have apparently been changed to use
    DEFCONSTANT instead.

  Objections:
    Some people don't think that DEFPARAMETER was intended to be used
    in this way and that this would be an incompatible change.

    
Proposal DEFCONSTANT-NOT-WIRED:RESTORE-DEFCONST:

  Leave DEFPARAMETER alone but add another construct with the semantics
  described above.

  Rationale:
    Some people don't think that DEFPARAMETER was intended to be used
    in this way.

  Objections:
    We haven't been able to come up with a good name for this construct.
    "DEFCONST" is too confusing and all of the other names that have
    been suggested are too long.  Also, having so many macros for 
    declaring variables with is confusing.


Proposal DEFCONSTANT-NOT-WIRED:NEW-DECLARATION:

  Add a new CONSTANT declaration to the language which can be used to 
  declare that a variable cannot be SETQ'd or bound within the scope of 
  the declaration.

  Rationale:
    This solves the problem and also provides more general functionality.
    For example, one could declare that a lexical variable won't be
    SETQ'ed.

  Objections:
    We haven't been able to decide whether a CONSTANT declaration should
    augment or replace a SPECIAL or LEXICAL declaration.  How do you 
    initialize a variable that has been proclaimed CONSTANT?  Some people 
    have objected to calling the declaration CONSTANT unless it is 
    equivalent to what a DEFCONSTANT does.


Proposal DEFCONSTANT-NOT-WIRED:ADD-OPTIONAL-ARGUMENT:

   Add an optional argument to DEFCONSTANT to indicate whether the
   compiler can make assumptions about the constant's value.

   Rationale:
     It would solve the problem.

   Objections:
     It would make DEFCONSTANT have different syntax from DEFVAR and
     DEFPARAMETER.


Proposal DEFCONSTANT-NOT-WIRED:DEFINE-VARIABLE

   Define a single macro, DEFINE-VARIABLE, that can be used to do what
   DEFVAR, DEFPARAMETER, and DEFCONSTANT now do, plus the proposed new
   functionality, plus possibly handle lexical variables as well
   (if proposal PROCLAIM-LEXICAL passes).  Arguments to the macro 
   could be used to control whether the value is allowed to change 
   and whether the compiler is allowed to make assumptions about the
   value.

   Rationale:
     It would solve the problem without cluttering up the language with
     new defining macros for every possible combination of behavior.

   Objections:
     Nobody has proposed anything definite yet.


Discussion:

This issue was discussed at length on the cl-compiler mailing list
last fall, without coming up with an acceptable proposal.  It didn't
appear that any of the alternatives had a great deal of support.  This
writeup summarizes the alternatives that have been proposed at various
times.  Some of them (particularly NEW-DECLARATION) have been
considered in detail, and others (DEFINE-VARIABLE) haven't been
pursued at all.

∂13-Mar-89  1533	X3J13-mailer 	issue DEFINE-OPTIMIZER, version 5   
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  15:33:36 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA09197; Mon, 13 Mar 89 16:31:22 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02562; Mon, 13 Mar 89 16:31:17 -0700
Date: Mon, 13 Mar 89 16:31:17 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903132331.AA02562@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue DEFINE-OPTIMIZER, version 5

Forum:	      Compiler
Issue:        DEFINE-OPTIMIZER
References:   Issue SYNTACTIC-ENVIRONMENT-ACCESS
Category:     ADDITION
Edit history: 28-Sep-88, Version 1 by Pitman
	      10-Mar-89, Version 2 by Pitman (clarifications, new example),
	      10-Mar-89, Version 3 by Pitman & Loosemore
	      11-Mar-89, Version 4 by Pitman
	      13-Mar-89, Version 5 by Loosemore (discussion)
Status:	      Ready for release

Problem Description:

  Often a general functional interface could be bypassed given explicit
  knowledge of the arguments passed. This may happen when the arguments
  are constant (or otherwise inferrable), an argument type is known (eg,
  due to use of THE or DECLARE), or when some particular pattern of
  optional, rest or keyword arguments is apparent.

  Most implementations provide internally for optimization of generalized
  function call interfaces to more specialized ones, but such an
  optimization facility is not provided to Common Lisp users.

  The absence of this facility in a portable fashion means that some
  CL programs run slower than they need to in some implementations, or
  else that some operators that should be implemented as functions end
  up getting implemented as macros to assure needed efficiency.

Proposal (DEFINE-OPTIMIZER:NEW-FACILITY):

  Introduce a facility for declaring compiler optimizations.

  DEFINE-OPTIMIZER name arglist {declaration}* {form}*		[Macro]

   Defines a compiler optimizer for a function named NAME. The ARGLIST,
   DECLARATIONS, and FORMS are treated exactly like the arglist, 
   declarations, and forms in a DEFMACRO. (The arglist may include
   &ENVIRONMENT and &WHOLE.)

   The argument NAME must name a function which has been previously
   defined. The effects of defining an optimizer for a locally or
   globally defined macro, a locally defined function, or a special 
   form are undefined.

   When the optimizer is invoked, the forms are executed in the context
   of bindings specified by the arglist, and two values are yielded,
   RESULT and VALID-P. (If either of the first or second return value
   is non-NIL, then the first return value is considered valid).

   If the result is valid, it is a form which is preferable to evaluate
   instead of the indicated call.

   If a call to DEFINE-OPTIMIZER appears at top-level in a file
   being processed by the file compiler, it also makes the optimizer 
   known at compile-time (similar to the way DEFMACRO makes a macro 
   definition known to the compiler).

  OPTIMIZE-EXPRESSION-1 form env				[Function]

   Similar to MACROEXPAND-1. Invokes the optimizers for the top level of
   FORM, but does not iterate on the result. Returns two values:
   RESULT and CHANGED-P. 

   Note: If an optimizer returns a result which is not valid,
    OPTIMIZE-EXPRESSION-1 hides the fact by returning FORM,NIL
    rather than NIL,NIL.

  OPTIMIZE-EXPRESSION form env					[Function]

   Iterates calling OPTIMIZE-EXPRESSION-1 until the CHANGED-P result
   is NIL.

  An implementation must save optimizer definitions created by
  DEFINE-OPTIMIZER in case OPTIMIZE-EXPRESSION is attempted, but is
  not actually required to call OPTIMIZE-EXPRESSION itself. Interpreters,
  for example, may choose to just call the unoptimized form.

  Using FLET and MACROLET shadow not only functions and their SETF methods,
  but also their optimizers.  No portable facility is provided for creating
  locally defined optimizers.

  The effect of defining optimizations for functions in the LISP package
  is not defined. (In some implementations, this would clobber or conflict
  with existing advice that may be of higher quality.)

  The editor is advised that a non-binding style note such as the
  following would also be appropriate:

    In general, it is poor style for a programmer to define optimizers for
    functions that he does not maintain. This is because the correct
    implementation of an optimizer for a function usually depends on an
    understanding of the internals of that function. As such, a function 
    definition and any optimizers should be maintained as a unit so that
    they can changes in either can be synchronized as appropriate with the
    other.

  The effect of using DEFINE-OPTIMIZER on a function declared to be
  INLINE is ``unspecified but harmless'' (per new Error Terminology).
  That is, since both operations (optimization and inlining) are intended
  to be semantics-preserving, no functional difference should be observed.
  However, in some implementations the presence of an optimizer may thwart
  the ability to inline, or vice versa. Writers of portable code are
  encouraged to use either DEFINE-OPTIMIZER or (PROCLAIM '(INLINE ...))
  but not both.

Example:

  ;; These examples are taken literally from the Macsyma sources,
  ;; modified only to change DEFOPT to DEFINE-OPTIMIZER. The comments
  ;; were specially written for the X3J13 audience.

  ;; M+ is adds a Macsyma expression to another Macsyma expression.
  ;; The Macsyma internal representation for the sum of X and Y is
  ;; ((MPLUS) X Y). A all the real work is done by SIMPLIFY, which
  ;; reduces the expression as needed necessary. However, SIMPLIFY
  ;; is very complicated, and considerable speed can be gained by
  ;; entering it at specific known places.

  (DEFUN M+ (&REST TERMS)
    (PROTECT-&REST-VARIABLE TERMS)
    (SIMPLIFY `((MPLUS) ,@TERMS)))

  (DEFINE-OPTIMIZER M+ (&REST TERMS)
    (COND ((= (LENGTH TERMS) 2) `(ADD2* ,@TERMS))
	  (T `(ADDN (LIST ,@TERMS) NIL))))

  ;; M- negates a Macsyma expression, or substracts two Macsyma
  ;; expressions. Once you figure out which of the two operations is
  ;; to be done, the problem is similar to that of M+ above. However,
  ;; often the decision can be made at compile time. In this case,
  ;; INLINE functions would have worked ok, except that not all
  ;; implementations do inlining, and even those that do may fail to
  ;; recognize that EXP2 being NIL means that a test can be eliminated
  ;; or dead code can be eliminated. Using optimizers is far more
  ;; likely to be useful in practice.

  (DEFUN M- (EXP1 &OPTIONAL (EXP2 NIL EXP2P))
    (IF (NOT EXP2P)
	(M--INTERNAL-NEGATE EXP1)
	(M--INTERNAL-SUBTRACT EXP1 EXP2)))

  (DEFINE-OPTIMIZER M- (EXP1 &OPTIONAL (EXP2 NIL EXP2P))
    (IF (NOT EXP2P)
	`(M--INTERNAL-NEGATE ,EXP1)
	`(M--INTERNAL-SUBTRACT ,EXP1 ,EXP2)))

Rationale:

  Many large portable applications expect such a facility on an 
  implementation-specific basis. Others would use one if available.

  Even if implementations don't use the provided optimizers primitively,
  user macros and code-walkers can invoke them, so the facility wouldn't
  be completely useless even in those implementations.

Current Practice:

  Symbolics Genera provides an optimizer facility which is more elaborate
  but not fundamentally incompatible with this facility.

  Many (if not most) serious implementations provide a similar facility.
  For example, Lucid provides "compiler macros" which serve the same
  purpose.

Cost to Implementors:

  Since the implementation is not required to use this facility, the
  cost of providing the proposed support is very small.

Cost to Users:

  None. This change is upward compatible.

Cost of Non-Adoption:

  Portable code would be slower than necessary in some situations.

Benefits:

  Some existing non-portable code could become portable.

Aesthetics:

  Providing a separate optimizer definition from a main function definition
  makes a possibility that the optimizer and main function could drift out
  of synch. However, most places where this gets used in the first place
  are places where speed is of paramount importance and the programmer is
  willing to invest effort in maintaining things correctly and to accept the
  risk of lossage if s/he fails.

  This is a fairly clean and simple extension which adds significant
  power to the compiler.

Discussion:

  Pitman strongly supports this proposal, the design of which is modeled
  directly after that which has been used in Macsyma for many years.

  Information about argument type can come from two different sources:
  THE and declarations (via PROCLAIM or DECLARE). The former information
  is portably accessible, the latter is not.  While a separate proposal
  (SYNTACTIC-ENVIRONMENT-ACCESS) for allowing program access to type
  declarations would be make this facility more useful, it is still
  quite useful without it, as the examples from Macsyma illustrate.

  Some implementations provide a way to provide more than one optimizer
  for the same function. A multiple optimizer facility can be written
  in terms of this simpler facility and vice versa, so the simpler of
  the two facilities is proposed here.

  Some people have suggested that they would like to see a pattern
  matching facility integrated into this facility. The design of a
  facility that would satisfy everyone would take a lot of time and
  effort. At this point, there is no chance that the design of such a
  facility would occur in time for acceptance into the standard.
  The choice is this or nothing. Pitman thinks the language is much
  better off with some form of optimization support than none.

  Loosemore says:
    Although I don't really think this is an essential feature to include
    in the standard, I don't have any strong objection to adding it.  If
    people think it's a good idea to provide a standard interface for this
    kind of thing, this is a good proposal for doing it -- it's fairly
    simple, doesn't introduce any radically new ideas, and is general
    enough to allow alternate interfaces (such as the pattern matcher) to
    be layered on top of it.

  Barrett says:
    I think you may have gotten the sense of Cris' INLINE comment wrong.
    I believe what he was suggesting is that NOTINLINE declarations should
    inhibit optimizers, a position I agree with.  I also think it would be
    better to specify the behavior when both an optimizer and an inline
    are present, rather than leaving it 'unspecified but harmless'.  I'd
    suggest that optimizers have precedence.  The rational is that this
    allows an optimizer to look for special patterns in the arguments, and
    to defer to the inline if it doesn't find them.  Of course, there's
    the problem that the compiler might then ignore the inline.

∂13-Mar-89  1536	X3J13-mailer 	issue DEFINING-MACROS-NON-TOP-LEVEL, version 8
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  15:36:01 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA09314; Mon, 13 Mar 89 16:33:46 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02565; Mon, 13 Mar 89 16:33:44 -0700
Date: Mon, 13 Mar 89 16:33:44 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903132333.AA02565@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue DEFINING-MACROS-NON-TOP-LEVEL, version 8

Forum:		Compiler
Issue:		DEFINING-MACROS-NON-TOP-LEVEL
References:	CLtL p. 66-70, 143
		Issue EVAL-WHEN-NON-TOP-LEVEL
		Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
		Issue COMPILER-LET-CONFUSION
Category:	CLARIFICATION, ENHANCEMENT
Edit History:   6-May-88, V1 by Sandra Loosemore
		9-Jun-88, V2 by Sandra Loosemore
		12-Sep-88, V3 by Sandra Loosemore (fix garbled section 4)
                21-Sep-88, V4 by Sandra Loosemore (clarify section 5)
		16-Dec-88, V5 by Sandra Loosemore (major restructuring)
		31-Dec-88, V6 by Sandra Loosemore (wording clarifications)
		07-Jan-89, V7 by Sandra Loosemore (add example)
		09-Mar-89, V8 by Sandra Loosemore (more restructuring)
Status:		Ready for release


Problem Description:

CLtL leaves the interpretation of defining forms such as DEFMACRO and
DEFVAR that appear in other than top-level locations unclear.

On page 66, it is stated: "It is not illegal to use these forms at
other than top level, but whether it is meaningful to do so depends on
context.  Compilers, for example, may not recognize these forms
properly in other than top-level contexts".  At least one implementation 
has interpreted this to mean that it is permissible to simply refuse
to compile defining macros that do not appear at top-level.


Proposal DEFINING-MACROS-NON-TOP-LEVEL:ALLOW:

(1) Remove the language from p. 66 of CLtL quoted above.  Clarify that
while defining macros normally appear at top level, it is meaningful
to place them in non-top-level contexts and that the compiler must
handle them properly in all situations.  However, the compile-time side
effects described in issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS 
only take place when the defining macros appear at top-level.

(2) Remove the language on p. 145 of CLtL, which states that macro
functions are always defined in the null lexical environment.  Clarify
that all defining macros which create functional objects (including
DEFMACRO, DEFTYPE, DEFINE-SETF-METHOD, and the complex form of
DEFSETF, as well as DEFUN) must ensure that those functions are
defined in the lexical environment in which the defining form is
evaluated.

(3) Specify that top-level forms in a file being compiled are
guaranteed to be processed sequentially.  The order in which
non-top-level subforms of a top-level form are processed by the
compiler is explicitly left unspecified.


Rationale:

This proposal makes the rules for when defining macros cause
compile-time side effects to be exactly the same as the rules for when
(EVAL-WHEN (COMPILE) ...) causes compile-time evaluation.  This
provides a simple implementation technique.

Item (3) serves two purposes.  First, it guarantees users that
compile-time side-effects from top-level EVAL-WHEN forms or defining
macros will happen in the correct order; programmers can depend upon
the compile-time side-effects of a top-level form being visible during
the compilation of subsequent forms.  Second, it allows compilers to
perform certain kinds of source-to-source transformations that change
the order of subforms.

For instance, the following example from CLtL

  (let ((old-count *access-count*))
      (unwind-protect
          (progn 
	      (incf *access-count*)
	      (perform-access))
	  (setq *access-count* old-count)))

is entirely equivalent to:

  (let ((old-count *access-count*))
      (let ((thunk  #'(lambda () (setq *access-count* old-count))))
          (unwind-protect
	      (progn
	          (incf *access-count*)
		  (perform-access))
	      (funcall thunk))))

(This is a real example from the A-Lisp compiler, which implements
UNWIND-PROTECT by having it push a "thunk" to perform the cleanup
actions onto the catch stack before executing the protected form.)


Current Practice:

Most implementations do allow defining macros in non-top-level places.
However, the rules for when they cause compile-time side-effects are
not always the same as those for EVAL-WHEN.  This is the case in
Lucid Common Lisp, for example.


Cost to implementors:

Implementations that currently don't compile defining macros correctly
when they appear at non-top-level will have to be changed.


Cost to users:

None.  This is a compatible extension.


Benefits:

The notion of defining macros as being somehow special when they
appear at top-level is removed, since their behavior can be explained
using EVAL-WHEN as a primitive.  Allowing defining macros to appear
anywhere instead of restricting them to certain positions results in a
cleaner language design.


Discussion:

This proposal is consistent with the behavior specified in proposal
EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL.  In particular, if the compile
time side-effects for defining macros specified in proposal
COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY are implemented using
EVAL-WHEN, the "right" compiler behavior for defining macros at
non-top-level will happen automatically.

∂13-Mar-89  1545	X3J13-mailer 	issue EVAL-WHEN-NON-TOP-LEVEL, version 6 
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  15:45:11 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA09664; Mon, 13 Mar 89 16:42:59 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02574; Mon, 13 Mar 89 16:42:54 -0700
Date: Mon, 13 Mar 89 16:42:54 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903132342.AA02574@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue EVAL-WHEN-NON-TOP-LEVEL, version 6

This issue has been giving us a lot of trouble for a long time.  A few
people on the cl-compiler mailing list have expressed discontent with
the proposals included here, but the dissenters haven't been able to
come up with an acceptable alternative proposal that they can all agree 
on.

Issue:        EVAL-WHEN-NON-TOP-LEVEL
Forum:        Compiler
References:   EVAL-WHEN (CLtL pp69-70),
              Issue DEFINING-MACROS-NON-TOP-LEVEL
	      Issue COMPILED-FUNCTION-REQUIREMENTS
	      Issue IN-PACKAGE-FUNCTIONALITY
	      Issue LOCALLY-TOP-LEVEL
Category:     CLARIFICATION/CHANGE
Edit History: 06-May-88, Version 1 by Sandra Loosemore
              16-Dec-88, Version 2 by Loosemore (alternate direction)
              30-Dec-88, Version 3 by Loosemore (minor wording changes)
              07-Jan-89, Version 4 by Loosemore (update discussion)
              09-Feb-89, Version 5 by Pitman and Moon (some major changes)
	      09-Mar-89, Version 6 by Loosemore (clean up wording)
Status:       Ready for release

Problem Description:

  The current description of how the compiler should handle EVAL-WHEN
  only makes sense when it appears as a top-level form in the file being
  compiled. Is it legitimate for EVAL-WHEN to appear in non-top-level
  locations? Even if it is legitimate, what does it mean?
 
  Another issue, referred to here as ``the EVAL-WHEN shadowing problem,''
  is that some people have complained that shadowing the symbols EVAL,
  COMPILE, or LOAD means that you have to also either shadow EVAL-WHEN
  and define it to recognize the new symbol, or else you must resign
  yourself to writing (EVAL-WHEN (... LISP:EVAL ...) ...),etc. all over.
  While the goal here is not to solve this problem, it might be possible
  to solve both problems at once.

  There are two proposals presented here, GENERALIZE-EVAL and
  GENERALIZE-EVAL-NEW-KEYWORDS.


Background/Analysis:

  The proposal which follows was constructed with the following goals
  in mind:

    1. The lexical and dynamic environment for the EVAL-WHEN body should
       be the same for each situation.  That is, the body should ``mean
       the same thing'' regardless of which situation is being processed.

    2. The evaluation context for EVAL-WHEN should be the current
       lexical environment.

    3. At execution time, EVAL-WHEN should always return the result of
       its last form if execution of the body occurred, or NIL if the
       body was not executed.

    4. If a top-level EVAL-WHEN has a LOAD keyword, its body should 
       inherit top-level-ness during normal processing. This permits the
       use of (EVAL-WHEN (EVAL COMPILE LOAD) ...) at top-level to mean
       simply "Do whatever would normally be done for this body, but
       also do something at compile time." This, in turn, will later be
       the key to allowing defining forms to be usefully described in
       terms of EVAL-WHEN.

    5. Non-top-level expressions should have no effect until they are
       executed. This is the key to making sure that any necessary
       environment is present. Since the COMPILE keyword forces effects
       to occur earlier than execution time, it follows from this that
       any correct solution must not allow the COMPILE keyword to have
       an effect at other than top-level.

  To accomplish these goals, we formulated the following model:

    The purpose of EVAL-WHEN is to accomodate the fact that some of the
    semantic processing of an expression may usefully be partitioned
    between compile time and run time in some circumstances.

    (EVAL-WHEN (EVAL) <code>)
    describes a general technique for accomplishing some particular goal
    at normal program execution time. However, the pair of expressions
    (EVAL-WHEN (COMPILE) <code-A>)
    (EVAL-WHEN (LOAD) <code-B>)
    can be used to describe an alternate technique for implementing part
    of the effect (A) at compile-time, and part of the effect (B) at
    load-time.


Proposal (EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL):

  Replace the description of EVAL-WHEN with the following:

  EVAL-WHEN ({situation}*) {form}*                      [Special Form]

  The body of an EVAL-WHEN form is processed as an implicit PROGN, but
  only in the situations listed.  Each SITUATION must be a symbol,
  either COMPILE, LOAD, or EVAL.

  The use of COMPILE and LOAD controls whether and when processing
  occurs for top-level forms. The use of EVAL controls whether
  processing occurs for non-top-level forms.

  The EVAL-WHEN construct may be more precisely understood in terms of
  a model of how the file compiler, COMPILE-FILE, processes forms in a
  file to be compiled.

  Successive forms are read from the file by the file compiler using 
  READ. These top-level forms are normally processed in what we call
  `not-compile-time' mode. There is one other mode, called 
  `compile-time-too' mode, which can come into play for top-level
  forms. The EVAL-WHEN special form is used to annotate a program
  in a way that allows the program doing the processing to select
  the appropriate mode.

  Processing of top-level forms in the file compiler works as follows:

   * If the form is a macro call, it is expanded and the result is
     processed as a top-level form in the same processing mode
     (compile-time-too or not-compile-time).

   * If the form is a PROGN form, each of its body forms is
     sequentially processed as top-level forms in the same processing
     mode.

   * If the form is a COMPILER-LET, MACROLET, or SYMBOL-MACROLET,
     the file compiler makes the appropriate bindings and recursively
     processes the body forms as an implicit top-level PROGN with those 
     bindings in effect, in the same processing mode.

   * If the form is an EVAL-WHEN form, it is handled according to
     the following table:

     COMPILE LOAD EVAL compile-time-too Action
     
       Yes   Yes  --     --             Process body in compile-time-too mode
       No    Yes  Yes    Yes            Process body in compile-time-too mode
       No    Yes  Yes    No             Process body in not-compile-time mode
       No    Yes  No     --             Process body in not-compile-time mode
       Yes   No   --     --             Evaluate body
       No    No   Yes    Yes            Evaluate body
       No    No   Yes    No             do nothing
       No    No   No     --             do nothing

     "Process body" means to process the body as an implicit top-level
     PROGN.  "Evaluate body" means to evaluate the body forms as in
     implicit PROGN in the dynamic execution context of the compiler and
     in the lexical environment in which the EVAL-WHEN appears.

   * Otherwise, the form is a top-level form that is not one of the
     special cases.  If in compile-time-too mode, the compiler first
     evaluates the form and then performs normal compiler processing
     on it.  If in not-compile-time mode, only normal compiler
     processing is performed.  [The nature of this processing is
     defined more precisely in issue COMPILED-FUNCTION-REQUIREMENTS.]
     Any subforms are treated as non-top-level forms.

  For an EVAL-WHEN form that is not a top-level form in the file compiler
  (that is, one of: in the interpreter; in COMPILE; or in the file
  compiler but not at top-level), if the EVAL situation is specified,
  its body is treated as an implicit PROGN.  Otherwise, the EVAL-WHEN
  form returns NIL.


 Clarifications/Consequences:

  The following effects are logical consequences of the above proposal:

   * It is never the case that the execution of a single EVAL-WHEN
     expression will execute the body code more than once.

   * The keyword `EVAL' is a misnomer because execution of
     the body need not be done by EVAL. In compiled code, such as
     (DEFUN FOO () (EVAL-WHEN (EVAL) (PRINT 'FOO)))
     the call to PRINT should be compiled.

   * Macros intended for use in top-level forms should arrange for all
     side-effects to be done by the forms in the macro expansion.
     The macro-expander itself should not do the side-effects.

       Wrong:  (defmacro foo ()
                 (really-foo)
                 `(really-foo))
    
       Right:  (defmacro foo ()
                 `(eval-when (compile eval load) (really-foo)))

     Adherence to this convention will mean that such macros will behave
     intuitively when placed in non-top-level positions.

   * Placing a variable binding around an EVAL-WHEN reliably captures the
     binding because the `compile-time-too' mode cannot occur (because 
     introducing a variable binding would mean we were not at top level).
     For example,

        (LET ((X 3))
          (EVAL-WHEN (EVAL LOAD COMPILE) (PRINT X)))

     will print 3 at execution [load] time, and will not print anything at
     compile time.  This is important so that expansions of DEFUN and 
     DEFMACRO can be done in terms of EVAL-WHEN and can correctly capture
     the lexical environment.

        (DEFUN BAR (X) (DEFUN FOO () (+ X 3)))

     might expand into

        (DEFUN BAR (X) 
          (PROGN (EVAL-WHEN (COMPILE) 
                   (COMPILER::NOTICE-FUNCTION-DEFINITION 'FOO '(X)))
                 (EVAL-WHEN (EVAL LOAD)
                   (SETF (SYMBOL-FUNCTION 'FOO) #'(LAMBDA () (+ X 3))))))

     which would be treated the same as

        (DEFUN BAR (X) 
          (SETF (SYMBOL-FUNCTION 'FOO) #'(LAMBDA () (+ X 3))))

     by the above rules.


 Test Cases:

  ;; #1: The EVAL-WHEN in this case is not at top-level, so only the EVAL
  ;;     keyword is considered. At compile time, this has no effect.
  ;;     At load time (if the LET is at top level), or at execution time
  ;;     (if the LET is embedded in some other form which does not execute
  ;;     until later) this sets (SYMBOL-FUNCTION 'FOO1) to a function which
  ;;     returns 1.
 
  (LET ((X 1))
    (EVAL-WHEN (EVAL LOAD COMPILE)
      (SETF (SYMBOL-FUNCTION 'FOO1) #'(LAMBDA () X))))
 
  ;; #2: If this expression occurs at the top-level of a file to be compiled,
  ;;     it has BOTH a compile time AND a load-time effect of setting
  ;;     (SYMBOL-FUNCTION 'FOO2) to a function which returns 2.
 
  (EVAL-WHEN (EVAL LOAD COMPILE)
    (LET ((X 2))
      (EVAL-WHEN (EVAL LOAD COMPILE)
        (SETF (SYMBOL-FUNCTION 'FOO2) #'(LAMBDA () X)))))
 
  ;; #3: If this expression occurs at the top-level of a file to be compiled,
  ;;     it has BOTH a compile time AND a load-time effect of setting the
  ;;     function cell of FOO3 to a function which returns 3.
 
  (EVAL-WHEN (EVAL LOAD COMPILE)
    (SETF (SYMBOL-FUNCTION 'FOO3) #'(LAMBDA () 3)))
 
  ;; #4: This always does nothing. It simply returns NIL.
 
  (EVAL-WHEN (COMPILE)
    (EVAL-WHEN (COMPILE) 
      (PRINT 'FOO4)))
 
  ;; #5: If this form occurs at top-level of a file to be compiled, FOO5 is
  ;;     printed at compile time. If this form occurs in a non-top-level
  ;;     position, nothing is printed at compile time. Regardless of context,
  ;;     nothing is ever printed at load time or execution time.
 
  (EVAL-WHEN (COMPILE) 
    (EVAL-WHEN (EVAL)
      (PRINT 'FOO5)))

  ;; #6: If this form occurs at top-level of a file to be compiled, FOO6 is
  ;;     printed at compile time.  If this form occurs in a non-top-level
  ;;     position, nothing is printed at compile time. Regardless of context,
  ;;     nothing is ever printed at load time or execution time.

  (EVAL-WHEN (EVAL LOAD)
    (EVAL-WHEN (COMPILE)
      (PRINT 'FOO6)))
 
 Rationale:
  
  This is compatible with any guarantees made by CLtL, and extends the
  behavior usefully to non-top-level situations.

  This gives a useful meaning to EVAL-WHEN that supports useful and
  predictable behavior if defining macros are used in a non-top-level
  situation.


Proposal (EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL-NEW-KEYWORDS):

  As in GENERALIZE-EVAL, but rename the EVAL keyword to :EXECUTE,
  the COMPILE keyword to :COMPILE-TOPLEVEL, and LOAD keyword to 
  :LOAD-TOPLEVEL.

  Deprecate the use of keywords EVAL, COMPILE, and LOAD to EVAL-WHEN.
  For compatibility, they are supported in EVAL-WHEN
  at top-level, but their meaning is not defined elsewhere.

 Rationale:

  The fact that the situation keywords chosen are not the same as
  those now used means that the change can be added in a way that
  is truly upward compatible (not only with CLtL but with existing
  practice in implementations which have chosen to extend or `clarify'
  the definition given in CLtL) since the meaning of EVAL, COMPILE,
  and LOAD in non-top-level situations (which was never spelled
  out in CLtL) can legitimately differ from the meaning of these
  new keywords.

  Using other names and/or the keyword package for the names of
  situations solves the EVAL-WHEN shadowing problem.

  The name `execute' does not promote the confusion that the body of an
  EVAL-WHEN must be executed only in the evaluator. It also does not
  promote the confusion that the body of an EVAL-WHEN, regardless of when
  executed, must run interpreted.

  The names `compile-toplevel' and `load-toplevel' emphasize the fact
  that these cases are not interesting in non-top-level positions.


Current Practice:

  In Symbolics Genera, the interpreter permits EVAL-WHEN in non-top-level 
  positions in a way that is compatible with this proposal but both the
  COMPILE and COMPILE-FILE functions complain about EVAL-WHEN in a
  non-top-level position.

  Both Lucid Common Lisp and Kyoto Common Lisp already interpret the
  EVAL keyword to mean "execute" in non-top-level situations.  Both of
  these implementations also make (EVAL-WHEN (LOAD) ...) suppress
  compile-time "magic" from defining macros such as DEFMACRO.

  IIM describes its EVAL-WHEN as:
   (defmacro eval-when (situations &body body &environment env)
     (if (not (compiler-environment-p env))
         (when (member 'eval situations) `(progn ,@body))
         (progn
           (when (member 'compile situations)
             (if (compiler-at-top-level-p env)
                 (mapc #'eval body)
                 (warn "Top-level form encountered at non-top-level.")))
           (when (member 'load situations) `(progn ,@body)))))
  Note that the interpretation of the EVAL situation and the nesting
  behavior is different.


Cost to Implementors:

  The actual change to EVAL-WHEN in both cases is probably fairly
  localized and straightforward to make in most or all implementations.

  The second-order costs of proposal GENERALIZE-EVAL will vary depending
  on whether existing implementations have extended the definition of
  EVAL-WHEN in incompatible ways. If an implementation has made such
  extensions, there may be user and system code which depends on them
  and the cost of converting that code may be non-trivial. There is
  presumably also documentation impact.

  Proposal GENERALIZE-EVAL-NEW-KEYWORDS avoids most or all of the 
  second-order costs of proposal GENERALIZE-EVAL.

  The compiler processing for top-level forms might be implemented 
  something like:

  ;;; Forms read by the file compiler are passed to PROCESS-TOP-LEVEL-FORM
  ;;;    with a env compile-time-too both NIL.
  
  (defun process-top-level-form (form env compile-time-too)
      (setq form (macroexpand form env))
      (cond ((not (consp form))
             nil)
            ((eq (car form) 'progn)
             (dolist (f (cdr form))
                 (process-top-level-form f env compile-time-too)))
            ((eq (car form) 'compiler-let)
             (process-compiler-let form env compile-time-too))
            ((eq (car form) 'macrolet)
             (process-macrolet form env compile-time-too))
            ((eq (car form) 'symbol-macrolet)
             (process-symbol-macrolet form env compile-time-too))
            ((eq (car form) 'eval-when)
             (process-eval-when form env compile-time-too))
            (t
             (if compile-time-too
                 (internal-eval form env))
             (compile-form form env))
            ))
  
  (defun process-eval-when (form env compile-time-too)
      (let* ((situations  (cadr form))
             (body        (cddr form))
             (compile-p   (member 'compile situations))
             (load-p      (member 'load situations))
             (eval-p      (member 'eval situations)))
          (cond ((or (and compile-p load-p)
                     (and eval-p load-p compile-time-too))
                 (process-top-level-form `(progn ,@body) env t))
                (load-p
                 (process-top-level-form `(progn ,@body) env nil))
                ((or compile-p
                     (and eval-p compile-time-too))
                 (dolist (f body)
                     (internal-eval f env)))
                (t
                 nil))))
  
  ;;; PROCESS-COMPILER-LET, PROCESS-MACROLET, and PROCESS-SYMBOL-MACROLET
  ;;;    do the obvious things.
  ;;; INTERNAL-EVAL evaluates "form" in lexical environment "env".


Cost to Users:

  Technically, none. Either proposal is technically upward compatible
  with CLtL.

  Proposal GENERALIZE-EVAL might force some extended implementations to
  change incompatibly. As such, some users who depend on 
  implementation-dependent extensions might have to adjust their code
  somewhat to deal with those changes.

  Proposal GENERALIZE-EVAL-NEW-KEYWORDS does not force implementations
  to change incompatibly, so has no forced impact on users.

Cost of Non-Adoption:

  EVAL-WHEN is a mess. Using it as the low-level substrate into which
  defining macros should expand, and guaranteeing any predictable effects
  of those macros in non-top-level situations is currently difficult and
  would continue to be so in the absence of some resolution on this issue.

Benefits:

  The costs of non-adoption would be avoided:  it would be possible to
  use EVAL-WHEN in many situations where it cannot currently be used
  reliably.

  The portability of many existing tools which use EVAL-WHEN internally
  in macros will be enhanced.

Aesthetics:

  This generalization of the meaning makes the purpose and uses of 
  EVAL-WHEN less mysterious. In that sense, aesthetics are simplified
  somewhat.


Discussion:

  The cleanup issue LOCALLY-TOP-LEVEL would make LOCALLY also "pass
  through" top-level-ness to its body.  The reason why that is not 
  addressed in this issue is that it involves making LOCALLY a special
  form.

  Pitman and Moon don't care whether we say `top level,' `top-level,' or
  `toplevel.' The spelling choices in this writeup are arbitrary. If
  necessary, the proposal GENERALIZE-EVAL-NEW-KEYWORDS could be amended
  to propose :COMPILE-TOP-LEVEL, etc.

  Pitman, Moon, and Bob Laddaga (a Symbolics Cloe implementor) support
  both of these proposals.  Pitman and Laddaga have a preference for
  GENERALIZE-EVAL-NEW-KEYWORDS.  Moon is neutral about which should be
  preferred.

  Sandra Loosemore says:
    I still feel somewhat uncomfortable with the definition of EVAL-WHEN
    presented here, mostly because its nesting behavior is so unintuitive
    (as in test case number 6).  We have also had a hard time in deciding
    what the term "top-level" really means; the definition presented here
    is rather arbitrary.  However, since we have run out of time in which
    to come up with acceptable alternatives, I'm willing to go along with
    proposal GENERALIZE-EVAL.  It is compatible with the description in
    CLtL but presented in a more coherent way, and I think it is an
    improvement.  On the other hand, I don't really like the idea of
    changing the names of the keywords; if we are going to make an
    incompatible change, the right thing to do would be to throw out
    EVAL-WHEN entirely and start from scratch.

∂13-Mar-89  1601	X3J13-mailer 	**DRAFT** issue MACRO-ENVIRONMENT-EXTENT, version 3
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  15:57:19 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA10215; Mon, 13 Mar 89 16:55:08 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02585; Mon, 13 Mar 89 16:55:05 -0700
Date: Mon, 13 Mar 89 16:55:05 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903132355.AA02585@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: **DRAFT** issue MACRO-ENVIRONMENT-EXTENT, version 3

This issue is still under discussion.  There are three proposals
presented formally and two more mentioned informally in the discussion
section, but it appears that the decision is really between proposal
DYNAMIC and everything else.

Forum:		Compiler
Issue:		MACRO-ENVIRONMENT-EXTENT
References:	CLtL p. 145-146
		Issue COMPILER-LET-CONFUSION
		Issue MACRO-CACHING
		Issue EVAL-WHEN-NON-TOP-LEVEL
		Issue SYNTACTIC-ENVIRONMENT-ACCESS
		CLOS Chapter 3 (89-003)
Category:	CLARIFICATION,CHANGE
Edit History:   V1, 10 Jan 1989, Sandra Loosemore
		V2, 09 Mar 1989, Sandra Loosemore
		V3, 13 Mar 1989, Sandra Loosemore (last-minute discussion)
Status:		**DRAFT**


Problem Description:

What is the extent of environment objects received as the &ENVIRONMENT
argument of a macro function?

CLtL says that &ENVIRONMENT is "useful primarily in the rare cases
where a macro definition must explicitly expand any macros in a
subform of the macro call before computing its own expansion".  While
this suggests that macro environment objects are typically used within
the dynamic scope of the macro function, the use of the word
"primarily" (rather than "only" or "exclusively" or some similarly
strong language) suggests that there may be other legitimate uses for
environment objects.  But, because CLtL is silent about what those
uses might be, many users and implementors are under the impression
that environment objects have only dynamic extent.

There are some situations where using environment objects as if they
had indefinite extent provides a very useful viewpoint from which to
solve a problem.  Consider the following example:

  (defmacro typed-var (var) var)

  (defmacro local-type-declare (declarations &body forms &environment env)
      `(macrolet ((typed-var (&whole w var)
		    (let ((type  (assoc var ',declarations)))
		      (if type 
		          `(the ,(cadr type) ,var)
                          (macroexpand w ',env)))))
	 ,@forms))

  (defun f (x y)
    (local-type-declare ((x fixnum) (y float))
      (+ (typed-var x) (typed-var y))))

Here, local macro TYPED-VAR is defined to look first in the innermost
lexical environment for information about the variable, and if there
isn't any then it recurses on the next outermost lexical environment.
The global definition of TYPED-VAR provides a terminal case to stop
the recursion.

There are other situations where the extent of macro environment
objects comes into play.  For example, if we allow caching of macro
expansions (issue MACRO-CACHING), environments must have indefinite
extent.  It is unclear whether CLOS would be affected by allowing
macro environments to have only dynamic extent.  (The descriptions of
the CLOS defining macros in document 89-003 seem to imply that the
value of the &ENVIRONMENT argument appears in the expansion of the
macro, but there now seems to be sentiment that the model of how the
defining macros work that is presented there is broken.)


Proposal MACRO-ENVIRONMENT-EXTENT:INDEFINITE:

State that macro environment objects received with the &ENVIRONMENT
argument of a macro function or as the argument to a *MACROEXPAND-HOOK*
function have indefinite extent.

Note that implementations are not permitted to destructively modify
lexical information in environment objects once they have been passed
to a macro function.  It is, however, permissible to add or remove
global definitions that are accessible through the environment.

  Rationale:

  This legitimizes the use of idioms which depend on macro environments
  having indefinite extent.

  Since data objects in Lisp otherwise have indefinite extent, it is
  more consistent to give environment objects indefinite extent as
  well.


Proposal MACRO-ENVIRONMENT-EXTENT:DYNAMIC:

State that macro environment objects received with the &ENVIRONMENT
argument of a macro function or with a *MACROEXPAND-HOOK* function
have only dynamic extent; the consequences are undefined if they are
referred to outside the dynamic extent of that macro function or hook
function.

  Rationale:

  This allows implementations to use somewhat more efficient techniques
  for representing environment objects.  For example, the storage could
  be stack-allocated, or environments could be bashed destructively
  instead of always being freshly heap-allocated.


Proposal MACRO-ENVIRONMENT-EXTENT:DYNAMIC-WITH-COPIER:

State that macro environment objects received with the &ENVIRONMENT
argument of a macro function or with a *MACROEXPAND-HOOK* function
have only dynamic extent; the consequences are undefined if they are
referred to outside the dynamic extent of that macro function or hook
function.

Add a new function:

COPY-ENVIRONMENT environment				[function]

This function returns an environment object that is semantically
equivalent to "environment" (which must be an object of the type
received with an &ENVIRONMENT argument to a macro or as an argument to
a *MACROEXPAND-HOOK* function), but which may safely be referred to
outside the dynamic extent of the macro function.  This function is
permitted to return an object that is EQ to its argument if that 
object may be safely used.

  Rationale:

  This allows implementations to use somewhat more efficient techniques
  for representing environment objects.  For example, the storage could
  be stack-allocated, or environments could be bashed destructively
  instead of always being freshly heap-allocated.

  It also allows programmers to use idioms that rely on environment
  objects having indefinite extent.


Current Practice:

Macro environments appear to have indefinite extent in Lucid Common
Lisp, Kyoto Common Lisp, CMU Common Lisp (at least in the
interpreter), Utah Common Lisp, and A-Lisp.  A-Lisp internally uses
the kind of idiom shown in the example above to implement FLET,
LABELS, and FUNCTION as macros.

Macro environments are stack-allocated in Symbolics Genera, and hence
have dynamic extent.

Macro environments also have dynamic extent on the TI Explorer,
because the compiler uses special variables are used to keep track of
lexical definitions.


Cost to implementors:

For proposal INDEFINITE, some implementations would need to change.  A
simple implementation of macro environments that would fit the
requirements of this proposal is to represent them as lists, pushing
information for inner contours onto the front of the list as the
contour is entered and popping the list when the contour is exited.

For proposal DYNAMIC, there is no associated implementation cost.

For proposal DYNAMIC-WITH-COPIER, the implementation cost is unknown
but probably fairly small in most implementations.


Cost to users:

For proposal INDEFINITE, there is no associated cost to users.

For proposal DYNAMIC, users would not be able to portably use a
simple and elegant approach to solving certain kinds of problems.

For proposal DYNAMIC-WITH-COPIER, users would have to remember to make
a copy of an environment object in some situations.


Benefits:

It is made clear whether treating environment objects as if they had
indefinite extent is portable usage.


Discussion:

Proposal SYNTACTIC-ENVIRONMENT-ACCESS:ADD-FUNCTIONAL-INTERFACE
includes adding a function called AUGMENT-ENVIRONMENT which could also
be used to create a copy of an environment.  However, it returns an
object with the same extent as its argument, and therefore can not
replace the function COPY-ENVIRONMENT under proposal
DYNAMIC-WITH-COPIER.

We have also considered a couple of other alternatives on this 
issue.

One alternative would be to give "remote" environments created by
COMPILE-FILE the extent of that call to COMPILE-FILE, while "local"
environments (the null lexical environment and environments created by
COMPILE and EVAL) would have indefinite extent.

Another alternative would be to say that environments created by
COMPILE-FILE, COMPILE, or EVAL have a dynamic extent that includes the
time when any other macro calls appearing lexically within the
expansion returned by the macro function are expanded.  This is
similar to the extent of the special bindings made by COMPILER-LET.

Both of these proposals could be combined with adding a copier
function to deal with those implementations where environments are
stack-allocated.  They would both solve the extent problem for the
example given in the problem description section, but not the general
problem of macro caching.  In conjunction with the proposals for issue
SYNTACTIC-ENVIRONMENT-ACCESS, they would both require some
modifications to implementations that currently give macro
environments dynamic extent.

Loosemore supports proposal MACRO-ENVIRONMENT-EXTENT:INDEFINITE.

Moon says:
  My opinion is that anything in CLOS that seems to depend on indefinite
  extent for macro environments is broken and needs to be fixed.  It's not
  broken because of the environment extent, but for other reasons.
  Thus I believe in dynamic extent for environments.

Neil Goldman says:
  In my code walker I have a pretty ugly way of dealing with MACROLET
  that would have been trivial if I could have counted on the
  ENVIRONMENT having indefinite extent.  There may be some cleaner way
  than what I did, but I just looked at PCL's code walker, and it also
  is much more complex than would be necessary if environments had
  indefinite extent.

∂13-Mar-89  1610	X3J13-mailer 	**DRAFT** issue PROCLAIM-ETC-IN-COMPILE-FILE (version 4)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  16:10:26 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA10862; Mon, 13 Mar 89 17:08:13 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02608; Mon, 13 Mar 89 17:08:10 -0700
Date: Mon, 13 Mar 89 17:08:10 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903140008.AA02608@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: **DRAFT** issue PROCLAIM-ETC-IN-COMPILE-FILE (version 4)

This is a new writeup for an issue that was first brought up several
months ago.  We haven't had time to review it thoroughly yet.

Issue:		PROCLAIM-ETC-IN-COMPILE-FILE
References:	CLtL p. 182 [package functions],
		  p. 156 [PROCLAIM], p. 439 [COMPILE-FILE];
                Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
		Issue IN-PACKAGE-FUNCTIONALITY
		Issue EVAL-WHEN-NON-TOP-LEVEL
		Issue DEFINING-MACROS-NON-TOP-LEVEL
Category:	CLARIFICATION, CHANGE, ADDITION
Edit History:   15 Sep 88, V1 by David Gray
                23 Sep 88, V2 by Sandra Loosemore (summarize discussion)
		11 Mar 89, V3 by Sandra Loosemore (rewrite)
		13 Mar 89, V4 by Sandra Loosemore (discussion)
Status:		**DRAFT**
 

Problem Description:

  Should the compiler treat top-level calls to PROCLAIM specially?

  Page 182 of CLtL says that COMPILE-FILE needs to treat top-level calls
  to the following package functions as though they were wrapped in an
  (EVAL-WHEN (COMPILE LOAD EVAL) ...):

    EXPORT  IMPORT  IN-PACKAGE  MAKE-PACKAGE SHADOW
    SHADOWING-IMPORT  UNEXPORT  UNUSE-PACKAGE  USE-PACKAGE

  CLtL is silent on whether top-level calls to PROCLAIM should also be
  evaluated at compile-time, which presumably means they shouldn't be.
  However, some implementations do evaluate PROCLAIM at compile-time.

  In the model of how COMPILE-FILE works that is presented in issues
  EVAL-WHEN-NON-TOP-LEVEL and DEFINING-MACROS-NON-TOP-LEVEL, the special
  form EVAL-WHEN is the only thing that can cause compile-time evaluation
  to occur.  The compile-time side-effects of macros such as DEFMACRO
  and DEFPACKAGE are explained by having them include EVAL-WHEN in their
  expansions.  Any functions that are treated specially, however, must
  be included as special cases in the compiler.

  Proposal IN-PACKAGE-FUNCTIONALITY:NEW-MACRO would remove the
  requirement that the package functions be treated specially.  Do we
  wish to make an exception to the model for PROCLAIM?


Proposal PROCLAIM-ETC-IN-COMPILE-FILE:YES:

  Require COMPILE-FILE to treat top-level calls to PROCLAIM as if they
  were wrapped in an (EVAL-WHEN (COMPILE LOAD EVAL) ...).

  Rationale:

    Proclamations affect compilation semantics and should be made 
    available to the compiler.


Proposal PROCLAIM-ETC-IN-COMPILE-FILE:NO:

  Clarify that calls to PROCLAIM should be treated the same as any
  other function call.  Users should wrap an explicit EVAL-WHEN around
  top-level calls to PROCLAIM if they want them to affect compilation.

  Rationale:

    This makes the semantics of COMPILE-FILE more uniform and easier 
    to understand.  In particular, if we remove the magic compile-time
    behavior of the package functions, it seems silly to add another
    exception for PROCLAIM.


Proposal PROCLAIM-ETC-IN-COMPILE-FILE:NEW-MACRO:

  Add a new macro:

  DEFPROCLAIM &rest decl-specs					[Macro]

  This macro PROCLAIMs the given <decl-specs>, which are not
  evaluated.  If a call to this macro appears at top-level in a file
  being processed by the file compiler, the proclamations are also
  made at compile-time.  As with other defining macros, it is 
  unspecified whether or not the compile-time side-effects of a 
  DEFPROCLAIM persist after the file has been compiled.

  Clarify that calls to PROCLAIM should be treated the same as any
  other function call.  Users should wrap an explicit EVAL-WHEN around
  top-level calls to PROCLAIM if they want them to affect compilation,
  or use the macro DEFPROCLAIM.

  Rationale:

    The macro makes the proclamations available to the compiler in such
    a way that does not require any special exceptions to be made in
    the model of how COMPILE-FILE works.

Current Practice:

  The TI explorer apparently implements proposal YES, except that
  (EVAL-WHEN (LOAD) (PROCLAIM '(OPTIMIZE ...))) doesn't do anything.
  The Symbolics compiler has special top-level handling for PROCLAIM,
  although the details are not clear.

  Lisps developed at Utah (UCL, A-Lisp, PSL/PCLS) do not give PROCLAIM
  any special compile-time handling.

  Lucid does not evaluate calls to PROCLAIM at compile-time.

  The IIM compiler has special top-level handling for PROCLAIM when
  the argument is a constant.  The information is recorded in the remote
  environment.

Cost to implementors:

  Since implementations are already required to have a mechanism for
  compile-time handling of the package functions, it would probably
  only require minor adjustments to add handling for PROCLAIM.

Cost to users:

  For proposal YES, users would have no way to suppress compile-time
  evaluation of a top-level call to PROCLAIM.  Wrapping it in an
  (EVAL-WHEN (EVAL LOAD)...) wouldn't work under the model of how
  EVAL-WHEN works in proposal EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL.

  Under any of these proposals, some users would probably have to
  make minor changes to their code.
  
Benefits:

  Users will know what to expect when they use PROCLAIM.
  
Costs of Non-Adoption: 

  Users will not know what to expect when they use PROCLAIM.

Aesthetics:

  At least two people consider requiring magic behavior for certain
  top-level function calls to be "semantically bletcherous".  Removing
  all special cases for functions that are implicitly evaluated at
  compile-time would simplify the model of how COMPILE-FILE works.

  Programs look cleaner if EVAL-WHEN is only needed for unusual cases
  instead of being required for the normal cases.
 
Discussion:

  The first version of this writeup also included REQUIRE with PROCLAIM,
  but we have now voted to remove REQUIRE from the language entirely.
  It also specified that OPTIMIZE proclamations should only have a local
  effect within the file being compiled.  This was removed for 
  consistency with other compile-time side-effects (such as those from
  DEFMACRO), where their persistence is explicitly left unspecified.

  Loosemore favors proposal NO, but wouldn't oppose proposal NEW-MACRO.

  Kim Barrett says:

    Proposal YES violates the general approach we've been taking of trying
    to limit side-effects on the local environment during compilation.

    Proposal NO makes PROCLAIM virtually worthless.

    Proposal NEW-MACRO -- While this matches up with other stuff we've
    been doing, I'm concerned about two things.  First, I really dislike
    the name DEFPROCLAIM.  This thing isn't defining anything!  It sounds
    like something that modifies the behavior of PROCLAIM, not something
    that actually makes a proclamation.  Second, I'm concerned about the
    cost to users.  I think the statement that

    "Under any of these proposals, some users would probably have to make 
    minor changes to their code."

    is rather misleading for this case.  There are a lot of PROCLAIMs out
    there.

Loosemore replies:

    ....but all of those uses of PROCLAIM are already nonportable.  No
    matter what we do here, somebody is going to get burned.

    Suggestions for better names for the macro are welcome.

∂13-Mar-89  1627	X3J13-mailer 	issue WITH-COMPILATION-UNIT, version 3   
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  16:27:44 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA11422; Mon, 13 Mar 89 17:25:34 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02634; Mon, 13 Mar 89 17:25:31 -0700
Date: Mon, 13 Mar 89 17:25:31 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903140025.AA02634@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: issue WITH-COMPILATION-UNIT, version 3

Forum:	      Compiler
Issue:        WITH-COMPILATION-UNIT
References:   COMPILE (p438), COMPILE-FILE (p439)
Category:     ADDITION
Edit history: 29-Sep-88, Version 1 by Pitman
	      10-Mar-89, Version 2 by Pitman (merge comments)
	      13-Mar-89, Version 3 by Loosemore (update discussion)
Status:	      Ready for release

Problem Description:

  Some actions done by the compiler (and particularly the file compiler)
  are typically deferred until the "very end" of compilation.  For example,
  some compilers complain about "functions seen but not defined".

  Unfortunately, since COMPILE-FILE is the largest unit of granularity,
  and since systems often extend over more than one file, it often happens
  that the compiler needlessly complains at the end of compiling one file
  about the absence of functions defined in the next file. 

Proposal (WITH-COMPILATION-UNIT:NEW-MACRO):

  Add the following new macro:

   WITH-COMPILATION-UNIT options &BODY forms			[Macro]

   Executes forms from left to right. Within the dynamic context
   of this form, actions deferred by the compiler until "the end of
   compilation" will be deferred until the end of the outermost call
   to WITH-COMPILATION-UNIT. The result(s) are the same as that of
   the last of the FORMS (or NIL if FORMS is null).

   OPTIONS is a keyword/value list, where only the values are
   evaluated. The set of keywords permitted may be extended by the
   implementation, but the only keyword defined by this standard is:

     :OVERRIDE boolean

       The default is NIL. If nested dynamically only the outer call
       to WITH-COMPILATION-UNIT has any effect unless BOOLEAN is T,
       in which case warnings are deferred only to the end of the
       innermost call.

  It follows that the functions COMPILE and COMPILE-FILE should
  provide the effect of (WITH-COMPILATION-UNIT (:OVERRIDE NIL) ...)
  around their code.

  Any implementation-dependent extensions may only be provided
  as the result of an explicit programmer request by use of 
  an implementation-dependent keyword.  Implementations are forbidden
  from attaching additional meaning to a conforming use of this
  macro.

  Note also that not all warnings are deferred. In some implementations,
  it may be that none are deferred. This proposal only creates an
  interface to the capability where it exists, it does not require the
  creation of the capability. An implementation which does not do 
  deferred warnings may correctly implement this as expanding into PROGN.

Test Case:

  (DEFUN COMPILE-FILES (&REST FILES)
    (WITH-COMPILATION-UNIT ()
      (MAPCAR #'(LAMBDA (FILE) (COMPILE-FILE FILE)) FILES)))

  (COMPILE-FILES "A" "B" "C")

  processes deferred warnings only after compiling all of A, B, and C.

Rationale:

  This will make the development of portable system-construction tools
  considerably more convenient. 

Current Practice:

  Lucid has a very similar facility, called WITH-DEFERRED-WARNINGS.

  TI Explorer and Symbolics Genera have a similar facility, which they
  call COMPILER-WARNING-CONTEXT-BIND.

Cost to Implementors:

  In implementations which have no deferred warnings, there is no cost.
  
  In implementations which have deferred warnings, the cost is probably
  fairly small -- usually just a matter of writing interfacing the 
  proposed macro to an existing one.

Cost to Users:

  None. This is a compatible addition.

Cost of Non-Adoption:

  Portable system-construction tools would continue to print lots of
  spurious warnings because they would have no way to tell the system
  that a set of files was working together.

Benefits:

  The cost of non-adoption is avoided.

Aesthetics:

  The ability to create a compilation unit other than a file is important.

Discussion:

  Pitman and Benson support this addition.

  One could imagine adding more options at a later date.

  It was the opinion of the compiler committee that there was room for
  expansion here to address issues like bounding the scope of global
  proclamations, sharing compile-time environments across files, etc.
  However, insufficient work was done on this to justify putting such
  a thing into the standard. The only clear need we have at this time
  was to defer warnings, but we chose a general name like 
  WITH-COMPILATION-UNIT rather than a specific name like Lucid's
  WITH-DEFERRED-WARNINGS in order to encourage implementations to 
  experiment with other kinds of options under implementation-specific
  keywords. Perhaps by the time of the next standard there will be
  sufficient understanding of this area to warrant further elaboration
  of this primitive.

  Kim Barrett says:

    I strongly oppose the behavior you proposed for compile and
    compile-file.  It is my belief that whether to override or not must be
    controlled through an argument to the compile functions, with the
    default being to override.  Otherwise, all existing code which makes
    use of the compile functions must be modified to protect itself by
    wrapping a (with-compilation-unit (:override t) ...) around the calls
    to the compiler.
    
    Consider a stream system built on an object system which will compose
    and compile functions on the fly on an as needed basis.  It would be
    very strange for the functions so generated while doing file io for
    the user's compile-file to have any relationship with said
    compile-file.
    
    I agree with your position that implementation-dependent extensions
    must be explicitly requested.

∂13-Mar-89  1622	X3J13-mailer 	**DRAFT** issue SYNTACTIC-ENVIRONMENT-ACCESS (version 4)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  16:22:04 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA11265; Mon, 13 Mar 89 17:19:53 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02631; Mon, 13 Mar 89 17:19:48 -0700
Date: Mon, 13 Mar 89 17:19:48 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903140019.AA02631@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: **DRAFT** issue SYNTACTIC-ENVIRONMENT-ACCESS (version 4)

This issue is also still under discussion.  This version of the writeup
is fairly new and hasn't been reviewed thoroughly yet.

Forum:		Compiler
Issue:          SYNTACTIC-ENVIRONMENT-ACCESS
References:     CLtL Chapter 8: Macros,
                Issue MACRO-FUNCTION-ENVIRONMENT,
                Issue GET-SETF-METHOD-ENVIRONMENT,
                Issue COMPILE-FILE-ENVIRONMENT
Related Issues: Issue FUNCTION-NAME,
		Issue PROCLAIM-LEXICAL
		Issue MACRO-ENVIRONMENT-EXTENT
Category:       ADDITION
Edit history:   Version 1, 2-Oct-88, Eric Benson
                Version 2, 17-Feb-89, Kim A. Barrett
		Version 3, 9-Mar-89, Kim A. Barrett (respond to comments)
		Version 4, 12-Mar-89, Sandra Loosemore (more revisions)
Status:         **DRAFT**

Problem description:

 When macro forms are expanded, the expansion function is called with
 two arguments: the form to be expanded, and the environment in which
 the form was found.  The environment argument is of limited utility.
 The only use sanctioned currently is as an argument to MACROEXPAND or
 MACROEXPAND-1 or passed directly as an argument to another macro
 expansion function.  Recent cleanup issues propose to allow it as an
 argument to MACRO-FUNCTION and to GET-SETF-METHOD.

 It is very difficult to write a code walker that can correctly handle
 local macro and function definitions, due to insufficient access to
 the information contained in environments and the inability to
 augment environments with local definitions.

 Some people believe that the CLOS meta-object protocol will require the
 ability to distinguish between remote environments used for compiling 
 to a file, from local environments used for processing by EVAL or
 COMPILE.  (However, there is no requirement in chapters 1 & 2 of the
 CLOS spec that things be done this way.)

 There are three proposals; SMALL, MEDIUM, and LARGE.


Proposal (SYNTACTIC-ENVIRONMENT-ACCESS:SMALL):

 The following functions provide information about syntactic
 environment objects.  In all of these functions the argument named ENV
 is an environment of the sort received by the &ENVIRONMENT argument to
 a macro or as the environment argument for EVALHOOK.  Optional "env"
 arguments default to NIL, which respresents the local null lexical
 environment (containing only global definitions and proclamations
 that are present in the runtime environment).  All of these functions
 should signal an error of type TYPE-ERROR if the value of an
 environment argument is not a syntactic environment.


 VARIABLE-KIND variable &optional env				[Function]

  VARIABLE is a symbol.  This function returns one of the following
  symbols, depending on the type of definition or binding which is
  apparent in ENV.

    NIL            There is no apparent definition or binding for variable.
    :SPECIAL       VARIABLE refers to a special variable, either declared 
                   or proclaimed. 
    :LEXICAL       VARIABLE refers to a lexical variable.
    :SYMBOL-MACRO  VARIABLE refers to a SYMBOL-MACROLET binding.
    :CONSTANT      VARIABLE refers to a named constant, defined by
                   DEFCONSTANT.

 [Note: If issue PROCLAIM-LEXICAL passes, then the :LEXICAL result
  will also refer to variables proclaimed lexical.] 

 Example:

  (DEFMACRO KIND-OF-VARIABLE (VAR &ENVIRONMENT ENV)
    `',(VARIABLE-KIND VAR ENV))

  (DEFVAR A)

  (DEFUN TEST ()
    (LET (B)
      (LET (C)
        (DECLARE (SPECIAL C))
        (SYMBOL-MACROLET ((D ANYTHING))
          (LIST (KIND-OF-VARIABLE A)
                (KIND-OF-VARIABLE B)
                (KIND-OF-VARIABLE C)
                (KIND-OF-VARIABLE D)
                (KIND-OF-VARIABLE E))))))

  (TEST) -> (:SPECIAL :LEXICAL :SPECIAL :SYMBOL-MACRO NIL)
      

 FUNCTION-KIND function &optional env				[Function]

  FUNCTION is a function name.  This function returns two values,
  depending on the type of function definition or function binding
  which is apparent for FUNCTION in ENV.

    NIL            There is no apparent definition for FUNCTION.
    :FUNCTION      FUNCTION refers to a function.
    :MACRO         FUNCTION refers to a macro.
    :SPECIAL-FORM  FUNCTION refers to a special form.

  The second value specifies whether the definition is local or
  global.  If local, the second value is true, and it is false when
  the definition is global. 

  Some function names may refer to both a global macro and a global
  special form.  In such a case, the macro takes precedence, and
  :MACRO is returned as the first value.

  [Note: The use of "function name" rather than "symbol" as the
   description of the function argument is intended to be compatible
   with the various proposals to extend the syntax of function
   specifiers.  If no such change actually occurs then this would only
   refer to symbols.]

 Example:

  (DEFMACRO KIND-OF-FUNCTION (FUNCTION-NAME &ENVIRONMENT ENV)
    `',(FUNCTION-KIND FUNCTION-NAME ENV))

  (DEFUN A ())

  (DEFMACRO B ())

  (DEFUN TEST ()
    (FLET ((C ()))
      (MACROLET ((D ()))
        (MULTIPLE-VALUE-CALL #'LIST
              (KIND-OF-FUNCTION A)
              (KIND-OF-FUNCTION B)
              (KIND-OF-FUNCTION QUOTE)
              (KIND-OF-FUNCTION C)
              (KIND-OF-FUNCTION D)
              (KIND-OF-FUNCTION E)))))

  (TEST) -> (:FUNCTION      NIL
             :MACRO         NIL
             :SPECIAL-FORM  NIL
             :FUNCTION      T
             :MACRO         T
             NIL            NIL)


 VARIABLE-TYPE variable &optional env				[Function]

  VARIABLE is a symbol.  This function returns the type specifier
  associated with the variable named by the symbol in the environment.
  If no explicit association exists, either by PROCLAIM or DECLARE,
  then the result is the type specifier T.

  The result of this function may not include all the apparent TYPE
  declarations for VARIABLE.  In particular, an implementation is free
  to ignore TYPE declarations, only returning TYPE information which
  was added to ENV by a call to AUGMENT-ENVIRONMENT.

 Example:

  This example assumes that the implementation records type
  information in the environment, rather than ignoring it.

  (DEFMACRO VARTYPE (VAR &ENVIRONMENT ENV)
    `',(VARIABLE-TYPE VAR ENV))

  (DEFVAR A 1)

  (PROCLAIM '(FIXNUM A))

  (DEFUN TEST ()
    (LET ((B (AREF "X" 0))
          (C 3))
      (DECLARE (STRING-CHAR B))
      (LIST (VARTYPE A) (VARTYPE B) (VARTYPE C))))

  (TEST) -> (FIXNUM STRING-CHAR NIL)


 FUNCTION-FTYPE function &optional env				[Function]

  FUNCTION is a function name.  This function returns the functional
  type specifier associated with the function in the environment, or
  the symbol FUNCTION if there is no functional type declaration or
  proclamation associated with the function.

  The result of this function may not include all the apparent FTYPE
  declarations for FUNCTION.  In particular, an implementation is free
  to ignore FTYPE declarations, only returning FTYPE information which
  was added to ENV by a call to AUGMENT-ENVIRONMENT.

 Example:

  This example assumes that the implementation records ftype
  information in the environment, rather than ignoring it.

  (DEFMACRO FUNTYPE (FUN &ENVIRONMENT ENV)
    `',(FUNCTION-FTYPE FUN ENV))

  (DEFUN A-FUNCTION (X)
    (+ X 3))

  (PROCLAIM '(FTYPE (FUNCTION (FIXNUM) FIXNUM) A-FUNCTION))

  (DEFUN TEST ()
    (FLET ((ANOTHER-FUNCTION (X)
             (+ X 2)))
      (DECLARE (FTYPE (FUNCTION (INTEGER) INTEGER) ANOTHER-FUNCTION))
      (LIST (FUNTYPE A-FUNCTION) (FUNTYPE ANOTHER-FUNCTION))))

  (TEST) -> ((FUNCTION (FIXNUM) FIXNUM) (FUNCTION (INTEGER) INTEGER))


 AUGMENT-ENVIRONMENT env &KEY variable
			      symbol-macro
                              function
                              macro
                              declare				[Function]

  This function returns a copy of ENV, augmented with the information
  provided by the keyword arguments.  The arguments are supplied as
  follows:

  :VARIABLE	A list of symbols which shall be visible as bound
		variables in the new environment.  Whether each
		binding is to be interpreted as special or lexical
		depends on SPECIAL declarations recorded in the
		environment or provided in the :DECLARE argument list.

  :SYMBOL-MACRO A list of symbol macro definitions, in the same format
                as the CADR of a SYMBOL-MACROLET special form.  The
		new environment will have local symbol-macro bindings
		of each symbol to the corresponding expansion, so that
		MACROEXPAND will be able to expand them properly.

  :FUNCTION	A list of function names which shall be visible as local
		function bindings in the new environment.

  :MACRO	A list of local macro definitions, in the same format
		as the CADR of a MACROLET special form.  The new
		environment will have local macro bindings of each
		name to the corresponding expander function, which
		will be returned by MACRO-FUNCTION and used by
		MACROEXPAND.

  :DECLARE	A list of decl-specs.  The new environment will 
		contain information about SPECIAL, TYPE, and FTYPE
		declarations appearing within the list.

  An error is signalled if any of the symbols naming macros in the
  :SYMBOL-MACRO alist are also included in the :VARIABLE list.
  An error is signalled if any of the names specified as keys in the
  :MACRO alist are also included in the :FUNCTION list.  The consequences
  of destructively modifying the list structure of any of the arguments
  to this function are undefined.

  The extent of the returned environment is the same as the extent of
  the argument.

  While an environment argument from EVALHOOK may be used as the
  environment argument for this function, the reverse is not true.  If
  an attempt is made to use the result of AUGMENT-ENVIRONMENT as
  the environment argument for EVALHOOK, the consequences are undefined.
  The environment returned by AUGMENT-ENVIRONMENT may only be used for
  syntactic analysis, ie. the functions specified by this proposal and
  functions such as MACROEXPAND.

  [If PROCLAIM-LEXICAL is adopted, LEXICAL declarations would also
   be recognized.]


 Rationale:

  This proposal defines a minimal set of accessors and a constructor
  for environments.

  The symbol-macro and macrolet definitions and declarations passed
  to AUGMENT-ENVIRONMENT are in the same form as those which would
  normally be encountered by a code-walker.  This makes it easier to
  use.  In particular, there is no need for users to write their own
  code to destructure macro arguments.

  Making TYPE and FTYPE information optional continues to allow
  implementations the freedom to simply ignore all such declarations.


Proposal (SYNTACTIC-ENVIRONMENT-ACCESS:MEDIUM):

 This is the same as proposal SMALL, but also includes:

 There are two kinds of environments, local and remote.  Local
 environments are created by EVAL and COMPILE, and are used in
 situations where the information in the environment pertains
 to the immediate running Lisp environment.  Remote environments
 are used by processors such as COMPILE-FILE to model what the
 Lisp environment will look like when the code being processed
 is actually loaded.

 If AUGMENT-ENVIRONMENT receives a remote environment as an argument,
 then the new environment returned by this function will also be 
 remote, and the two will refer to the same model of the remote
 environment.


 ENVIRONMENT-REMOTE-P env					[Function]

  Returns true if ENV is a remote environment, false otherwise.


 WITH-REMOTE-ENVIRONMENT var &body body     		[Macro]

  Evaluates the BODY forms with VAR bound to a newly created remote
  environment.  The extent of the environment is the dynamic extent of
  the WITH-REMOTE-ENVIRONMENT form.

  This is the only specified mechanism by which a new remote
  environment may be created.


 Rationale:

  The notion of local and remote environments may be useful for
  developing the CLOS meta-object protocol.  At some future time,
  we may wish to tighten the specification of how compile-time 
  definitions of defining macros such as DEFMACRO or DEFCLASS are
  achieved, by saying that the compile-time definitions must be made
  only in the remote environment.


Proposal (SYNTACTIC-ENVIRONMENT-ACCESS:LARGE):

 This is the same as proposal MEDIUM, but also includes:

 ENVIRONMENT-PROPERTY env name property &optional default

  This function and its SETF method allow the association of arbitrary
  'global' properties with names within an environment.  An
  environment can be thought of as having a local property list
  associated with any name, and this function provides access to that
  property list.

  A remote environment may be thought of as an extension of the local
  environment.  Thus, when this function is applied to a remote
  environment and the property is not found, the global local environment 
  is then searched.

  The association between names and property lists uses EQUAL to match
  names.  The search of the property list uses EQ to match properties.
  If the property is not found, DEFAULT is returned.

  Using SETF of ENVIRONMENT-PROPERTY affects all environments which
  refer to the same environment model.  In particular, if ENV is a
  local environment then all local environments are affected, while if
  ENV is a remote environment, then all environments refering to the
  same remote environment model as the argument are affected.

  [Note: The local property list of a name is not necessarily the
   symbol-plist of the name, though that is a possible implementation
   for names which are symbols. 

   Note: The use of EQUAL as the matching function for names is to
   allow for proposed extensions to function names.  If no such
   extension occurs, then EQ could be used instead.]


 Rationale:

  This would provide a mechanism for making and accessing global
  definitions in the remote environment.


Cost to Implementors:

 Most implementations already record some of this information in some
 form.  Providing these functions should not be too difficult, but it
 is a more than trivial amount of work.

Cost to Users:

 This change is upward compatible with user code.

Current practice:

 No implementation provides all of this interface currently.  Portable
 Common Loops defines a subset of this functionality for its code
 walker and implements it on a number of diffent versions of Common
 Lisp.  IIM uses the functionality provided by ENVIRONMENT-REMOTE-P
 and ENVIRONMENT-PROPERTY (under other names) to implement the
 association between names and remote metaobjects (macro and type
 definitions, CLOS remote metaobjects, &etc).

Discussion:

 The first version of this proposal expressly did not deal with the
 objects which are used as environments by EVALHOOK.  This version is
 extended to support them in the belief that such environments share a
 lot of functionality with the syntactic environments needed by a
 compiler.  While the two types of environments may have very
 different implementations, there are many operations which are
 reasonable to perform on either type, including all of the accessor
 functions described by this proposal.

 AUGMENT-ENVIRONMENT currently requires signaling an error when
 symbol-macro names match variable names in the same call.  This could
 be reduced to "should signal".  By requiring the error signaling, this
 proposal is compatable with Proposal SYMBOL-MACROLET-DECLARE:ALLOW,
 which says

   "... signals an error if a SPECIAL declaration names one of the symbols
   being defined as a symbol-macrolet."

 Maintaining compatability with the SYMBOL-MACROLET-DECLARE proposal
 allows fairly trivial implementations of the SYMBOL-MACROLET
 special-form in terms of the AUGMENT-ENVIRONMENT function.

 An possible alternative syntax for WITH-REMOTE-ENVIRONMENT might be
   WITH-REMOTE-ENVIRONMENT (var &key) &body body
 Can anyone suggest candidates for keyword options?  We could do this
 even if we can't think of any immediately, leaving room for
 implementation-specific extensions.  One candidate option that some
 implementations might want would be to specify a target machine for
 the compilation.

 Kim Barrett originally suggested that WITH-COMPILATION-UNIT should
 provide the mechanism for creating new remote environments.  However,
 it has been suggested that WITH-COMPILATION-UNIT is intended to serve
 a somewhat different purpose.

 Sandra Loosemore says:
  I support proposal SMALL but would vote against both of the larger
  proposals.  It's true that they provide functionality which *might* be
  useful to implement CLOS, but there is nothing now in the standard
  that *requires* this functionality to be added.  In fact, the version
  of issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS that was accepted at
  the January meeting explicitly leaves unspecified the mechanism by
  which defining macros make definitions available to the compiler.  We
  have very little practical experience with using environment objects
  for this purpose and I think it would be premature to try to
  standardize it at this point.  In particular, since the meta-object
  protocol is still undergoing what appear to be substantial changes,
  let's wait until it settles down and then see what kind of compiler
  hooks it needs, instead of possibly standardizing the wrong thing.


∂13-Mar-89  1643	X3J13-mailer 	issue COMPILER-LET-CONFUSION, version 7  
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 13 Mar 89  16:43:27 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Mon, 13 Mar 89 19:39:46 EST
Date: Mon, 13 Mar 89 19:41 EST
From: Barry Margolin <barmar@Think.COM>
Subject: issue COMPILER-LET-CONFUSION, version 7
To: cl-compiler@sail.stanford.edu
Cc: x3j13@sail.stanford.edu
In-Reply-To: <8903132314.AA02546@defun.utah.edu>
Message-Id: <19890314004109.1.BARMAR@OCCAM.THINK.COM>

    Date: Mon, 13 Mar 89 16:14:26 -0700
    From: sandra%defun@cs.utah.edu (Sandra J Loosemore)

	In interpreters which do not do a semantic-prepass, it is necessary
	to fully macroexpand the body. Assuming the presence of a
	SYSTEM::MACROEXPAND-ALL primitive, the definition of COMPILER-LET
	could look like:
	  (DEFMACRO COMPILER-LET (BINDINGS &BODY FORMS &ENVIRONMENT ENV)
	    (SETQ BINDINGS ;; Assure no non-atom bindings
		  (MAPCAR #'(LAMBDA (BINDING) 
			      (IF (ATOM BINDING) (LIST BINDING) BINDING))
			  BINDINGS))
	    (PROGV (MAPCAR #'CAR BINDINGS)
		   (MAPCAR #'CDR BINDINGS)
	      (SYSTEM::MACROEXPAND-ALL `(PROGN ,@FORMS) ENV)))

Modulo some bugs in the code.  Shouldn't the second-to-last line be:

	(MAPCAR #'(LAMBDA (BINDING)
		    (eval (CaDR BINDING)))
		BINDINGS)

(my additions are in lowercase)?

                                                barmar

∂13-Mar-89  1634	X3J13-mailer 	summary of active cl-compiler issues
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 13 Mar 89  16:34:43 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA11546; Mon, 13 Mar 89 17:32:30 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA02645; Mon, 13 Mar 89 17:32:27 -0700
Date: Mon, 13 Mar 89 17:32:27 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903140032.AA02645@defun.utah.edu>
To: x3j13@sail.stanford.edu
Reply-To: cl-compiler@sail.stanford.edu
Subject: summary of active cl-compiler issues

Here is a list of all the active cl-compiler issues.  Writeups for
all of these were mailed out earlier today.

CLOS-MACRO-COMPILATION (**DRAFT** version 2)
    Clarify compile-time behavior of CLOS defining macros.
      Proposal MINIMAL
      Proposal NOT-SO-MINIMAL
      (Still under active discussion.)

COMPILE-ENVIRONMENT-CONSISTENCY (version 4)
    What kinds of things can/must the compiler "wire in" to the code
    it compiles?
      Proposal CLARIFY

COMPILE-FILE-SYMBOL-HANDLING (version 2)
    How does COMPILE-FILE tell LOAD what package to put symbols in?
      Proposal CURRENT-PACKAGE
      Proposal HOME-PACKAGE
      Proposal REQUIRE-CONSISTENCY

COMPILED-FUNCTION-REQUIREMENTS (version 4)
    What does the COMPILED-FUNCTION type imply?  Do COMPILE and 
    COMPILE-FILE construct COMPILED-FUNCTIONs?
      Proposal TIGHTEN
      Proposal TIGHTEN-COMPILE

COMPILER-DIAGNOSTICS (version 9)
    Clarify status and handling of errors and warnings signalled during 
    compilation.
      Proposal USE-HANDLER    

COMPILER-LET-CONFUSION (version 7)
    The description of COMPILER-LET in CLtL is broken -- should we fix
    it or eliminate it entirely?
      Proposal REPAIR
      Proposal ELIMINATE

COMPILER-VERBOSITY (version 6)
    Mechanisms for controlling progress messages issued by the compiler.
      Proposal LIKE-LOAD
 
CONSTANT-CIRCULAR-COMPILATION (version 7)
    Must circular or recursive objects be compiled correctly?  Must the
    compiler preserve sharing of substructures?
      Proposal NO
      Proposal PRESERVE-SHARING-ONLY
      Proposal YES
      (Expect amendment to change error terminology.)

CONSTANT-COLLAPSING (version 5)
    Should the compiler be allowed to "collapse" or coalesce constants
    that satisfy a more general equivalence relationship than EQUAL?
      Proposal GENERALIZE

CONSTANT-COMPILABLE-TYPES (version 8)
    What types of objects can appear as quoted or self-evaluating constants
    in compiled code?
      Proposal SPECIFY
      (Expect amendments to change requirements for functions.)

DEFCONSTANT-NOT-WIRED (**DRAFT** version 6)
    How do you delcare a variable to be constant without giving the
    compiler permission to make assumptions about its value?
      (None of the proposals are ready to be voted on.  This issue
      is being distributed only for informational purposes.)

DEFINE-OPTIMIZER (version 5)
    Provide a macro-like way of specifying source-level optimizations
    on function calls.
      Proposal NEW-FACILITY

DEFINING-MACROS-NON-TOP-LEVEL (version 8)
    Are defining macros such as DEFUN meaningful in non-top-level locations?
      Proposal ALLOW

EVAL-WHEN-NON-TOP-LEVEL (version 6)
    What does EVAL-WHEN mean when it appears in non-top-level locations?
      Proposal GENERALIZE-EVAL
      Proposal GENERALIZE-EVAL-NEW-KEYWORDS

LOAD-TIME-EVAL (version 11)
    Add a new special form, LOAD-TIME-VALUE.
      Proposal R**2-NEW-SPECIAL-FORM
      Proposal R**3-NEW-SPECIAL-FORM
      (Proposal R**2-NEW-SPECIAL-FORM was approved at the January meeting,
      but some additional suggestions were made after the meeting.)

MACRO-CACHING (version 2)
    Is it legitimate to cache macro expansions?
      Proposal DISALLOW
      Proposal RESTRICT

MACRO-ENVIRONMENT-EXTENT (**DRAFT** version 3)
    Do environment objects received as the &ENVIRONMENT argument to a 
    macro have dynamic or indefinite extent?
      Proposal INDEFINITE
      Proposal DYNAMIC
      Proposal DYNAMIC-WITH-COPIER
      (Still under active discussion.)

PROCLAIM-ETC-IN-COMPILE-FILE (**DRAFT** version 4)
    Are top-level calls to PROCLAIM handled specially by the compiler?
      Proposal YES
      Proposal NO
      Proposal NEW-MACRO
      (New rewrite.)

QUOTE-SEMANTICS (version 2) (replaces QUOTE-MAY-COPY)
    May COMPILE and EVAL construct equivalent copies of quoted or 
    self-evaluating constants, or must constants share structure with
    the source code for the program?  Do the constraints on what objects
    are valid constants also apply to COMPILE and EVAL, or only to
    COMPILE-FILE?
      Proposal NO-COPYING
      Proposal COPYING-ALLOWED-BUT-NO-CONSTRAINTS
      Proposal SAME-AS-COMPILE-FILE

SAFE-CODE (version 1)
    What does the "safe code" mean?
      Proposal SAFETY-3

SYNTACTIC-ENVIRONMENT-ACCESS (**DRAFT** version 4)
    Provide accessors and constructors for lexical environment objects.
      Proposal SMALL
      Proposal MEDIUM
      Proposal LARGE
      (New rewrite.)

WITH-COMPILATION-UNIT (version 3)
    Provide a way to compile a group of files as a unit for the purposes
    of error messages.
      Proposal NEW-MACRO

∂14-Mar-89  0938	CL-Compiler-mailer 	issue COMPILER-LET-CONFUSION, version 7 
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89  09:37:46 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 556615; Tue 14-Mar-89 12:35:04 EST
Date: Tue, 14 Mar 89 12:35 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue COMPILER-LET-CONFUSION, version 7
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903132314.AA02546@defun.utah.edu>
Message-ID: <19890314173505.3.MOON@EUPHRATES.SCRC.Symbolics.COM>

I generally favor the COMPILER-LET-CONFUSION:REPAIR proposal, however
I have a couple of comments and questions.  Also of course I would want
to see the typo that BarMar found fixed.

What is the interaction between proposals COMPILER-LET-CONFUSION
and DEFINE-OPTIMIZER?  Neither proposal says anything about that
as far as I can see.  I believe the body of a optimizer must be
executed in the same dynamic environment as the body of a macro.

      Cost to Implementors:

	In interpreters which do not do a semantic-prepass, it is necessary
	to fully macroexpand the body. 

This is not true.  A possible implementation technique for such
interpreters, in fact the one I would use, is to save the COMPILER-LET
bindings in a slot in the interpreter's lexical environment in the form
of an alist, and to make the MACROEXPAND-1 function bind those bindings
with PROGV around its call to the macroexpander.  Using this technique
instead of fully macroexpanding the body deals with some of the
objections to the REPAIR proposal, I believe.  Also promoting this
technique in the proposal would remove the need for the discussion
section to address the side-issue of whether code analyzing programs can
or cannot be written portably (an important issue in its own right, but
not part this one).

    Current Practice:
  
     Some implementations have implemented the description in CLtL. 
     Users of those implementations (quite reasonably) can't figure how to 
     use COMPILER-LET and so don't use it much.

     Some implementations (the ones from which COMPILER-LET originally came)
     continue to use their pre-CLtL semantics. These semantics are useful, though
     incompatible with CLtL (which they largely consider to simply be in error).

Could you be more explicit about this?  I was unable to figure out what you
are talking about, even after twice reading the introductory portion of the
proposal and the writeup in CLtL.  I believe Symbolics Genera is one of those
implementations from which COMPILER-LET originally came and at the same time
implements COMPILER-LET exactly as CLtL specifies, so I must be missing some
important distinction.  I'd like to see a precise description of these two
competing semantics and I'd also like to know which, if either, of them is
compatible with the REPAIR proposal.

∂14-Mar-89  0956	CL-Compiler-mailer 	issue DEFINE-OPTIMIZER, version 5  
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89  09:56:35 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 556621; Tue 14-Mar-89 12:54:02 EST
Date: Tue, 14 Mar 89 12:54 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue DEFINE-OPTIMIZER, version 5
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903132331.AA02562@defun.utah.edu>
Message-ID: <19890314175403.4.MOON@EUPHRATES.SCRC.Symbolics.COM>

I generally like DEFINE-OPTIMIZER:NEW-FACILITY, but I would like
to suggest a couple of changes.

I'm not a fan of documentation strings, but shouldn't DEFINE-OPTIMIZER
allow them?  Was their omission accidental or intentional?

Instead of returning two values from the body, I suggest returning one
value, or NIL to decline to optimize.  If an optimizer wishes to
optimize into a form whose result is NIL, it should return (QUOTE NIL).
After all, if it wishes to optimize into a form whose result is FOO, it
has to return (QUOTE FOO), not FOO.  The two values returned by
OPTIMIZE-EXPRESSION-1 are okay, since they are compatible with the two
values returned by MACROEXPAND-1.  A reasonable alternative would be to
eliminate the two values at all levels, and also eliminate the special
casing of NIL, and simply specify that one declines to optimize by
returning the original form (compared with EQ).  This will work but is
slightly more awkward for the optimizer writer, since &WHOLE would
have to be used.  I'd accept this alternative if more people are in
favor of it, but I prefer special-casing NIL.  I'd greatly prefer either
of those alternatives over what the proposal says now.

It isn't made clear whether OPTIMIZE-EXPRESSION returns one value
or two.  It should be consistent with OPTIMIZE-EXPRESSION-1.

  Using FLET and MACROLET shadow...

I assume it was only accidental that LABELS, GENERIC-LABELS, and
GENERIC-FLET were omitted from this list.  I am unable to figure
out whether WITH-ADDED-METHODS should be included in this list
or not; I suspect not.

The similar Symbolics Genera facility allows more than one optimizer
to be defined for a given function; the optimizers are invoked in
unspecified order until one succeeds.  This feature is actually
used, however I think it is okay to leave it out.

I agree with Barrett's comments quoted in the discussion section.
I'd like to see the proposal amended the way he suggests.

∂14-Mar-89  1005	CL-Compiler-mailer 	issue WITH-COMPILATION-UNIT, version 3  
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89  10:05:29 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 556623; Tue 14-Mar-89 13:03:02 EST
Date: Tue, 14 Mar 89 13:03 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue WITH-COMPILATION-UNIT, version 3
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903140025.AA02634@defun.utah.edu>
Message-ID: <19890314180303.5.MOON@EUPHRATES.SCRC.Symbolics.COM>

I oppose this because I don't think it's finished, however I expect I
would support it if it were finished.  It may be that the amount of work
required to finish this is small and the proposal just needs amending.

I don't think it's acceptable to have something like this if its effect
is only defined for warnings, and its effect on compile-time
proclamations, compile-time macro definitions, compile-time defconstant
definitions, compile-time optimizer definitions, compile-time type
definitions, compile-time setf definitions, and compile-time CLOS
definitions is left unspecified.

I think lumping COMPILE and COMPILE-FILE together here reflects
confusion.  COMPILE and COMPILE-FILE have very little to do with each
other, and I think it's clear that COMPILE should not be affected in any
way by WITH-COMPILATION-UNIT.  Having COMPILE affected by
WITH-COMPILATION-UNIT is as unreasonable as having MACROEXPAND affected
by WITH-COMPILATION-UNIT, if you ask me.  I think removing COMPILE would
address Barrett's complaint in the discussion section; that is, I think
having COMPILE-FILE not override an enclosing WITH-COMPILATION-UNIT is
correct.

∂14-Mar-89  1217	CL-Compiler-mailer 	**DRAFT** issue MACRO-ENVIRONMENT-EXTENT, version 3    
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89  12:17:12 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 556715; Tue 14-Mar-89 15:09:52 EST
Date: Tue, 14 Mar 89 15:09 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** issue MACRO-ENVIRONMENT-EXTENT, version 3
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903132355.AA02585@defun.utah.edu>
Message-ID: <19890314200952.9.MOON@EUPHRATES.SCRC.Symbolics.COM>

I strongly favor MACRO-ENVIRONMENT-EXTENT:DYNAMIC over any of the other four.

∂14-Mar-89  1232	CL-Compiler-mailer 	**DRAFT** issue PROCLAIM-ETC-IN-COMPILE-FILE (version 4)    
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89  12:32:34 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 556743; Tue 14-Mar-89 15:29:24 EST
Date: Tue, 14 Mar 89 15:29 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** issue PROCLAIM-ETC-IN-COMPILE-FILE (version 4)
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903140008.AA02608@defun.utah.edu>
Message-ID: <19890314202917.0.MOON@EUPHRATES.SCRC.Symbolics.COM>

I favor PROCLAIM-ETC-IN-COMPILE-FILE:NEW-MACRO, primarily because this
allows programs to be clear about the scope of the proclamation:
whether they are making a proclamation for purposes of compile-file or
to affect the running Lisp.  If you call the macro at top-level, you're
clearly doing it for compilation.  If you call the function at any level,
you're clearly doing it with global scope.

In PROCLAIM-ETC-IN-COMPILE-FILE:NO there is no way to say whether a
PROCLAIM inside an (EVAL-WHEN (COMPILE...) ...)  is intended to persist
after the compilation is over, which is just about the only reason
why I prefer PROCLAIM-ETC-IN-COMPILE-FILE:NEW-MACRO over :NO.

I'd like PROCLAIM-ETC-IN-COMPILE-FILE:NO better if it also proposed
to add an optional argument to PROCLAIM that expressed the intended
scope of the proclamation.  I'd suggest NIL (the default) for the
global scope and the symbol COMPILE-FILE to limit it to the compilation.
Given this, users who liked DEFPROCLAIM could trivially write it
themselves.

The only thing PROCLAIM-ETC-IN-COMPILE-FILE:YES has going for it is
that it's the status quo, in a subset of implementations.  I don't like it.

I agree with Barrett's comments quoted in the discussion section.

The proposal says:
  As with other defining macros, it is 
  unspecified whether or not the compile-time side-effects of a 
  DEFPROCLAIM persist after the file has been compiled.
but never says this about PROCLAIM.  In all three proposals,
this needs to be said about PROCLAIM.  But as you can see from my
comments above, I would rather that we did not leave this unspecified.

The proposal says:
  Current Practice:
  
    The Symbolics compiler has special top-level handling for PROCLAIM,
    although the details are not clear.

I'm not sure what you thought was not clear.  Symbolics Genera does the
same thing that the current practice section says IIM does.  In addition
(and I couldn't tell whether IIM does this too or not), the scope of the
PROCLAIM is only the compilation-unit if the PROCLAIM appears at
top-level, but is global and persists forever if the PROCLAIM appears in
an (EVAL-WHEN (COMPILE...) ...).  We might change that.

∂14-Mar-89  1310	CL-Compiler-mailer 	issue DEFINING-MACROS-NON-TOP-LEVEL, version 8    
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89  13:09:32 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 556774; Tue 14-Mar-89 15:58:28 EST
Date: Tue, 14 Mar 89 15:58 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue DEFINING-MACROS-NON-TOP-LEVEL, version 8
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903132333.AA02565@defun.utah.edu>
Message-ID: <19890314205826.2.MOON@EUPHRATES.SCRC.Symbolics.COM>

I favor DEFINING-MACROS-NON-TOP-LEVEL:ALLOW except for one thing.
This sentence appears in the proposal but does not appear to have
any relation to the main issue:

  The order in which
  non-top-level subforms of a top-level form are processed by the
  compiler is explicitly left unspecified.

I can't figure out what this means and the example in the rationale
section that purports to explain this does not shed any light, since in
the example there is no change of order of evaluation.  I wouldn't be
surprised if I opposed this if I did understand what it means.  Can we
deal with this as a separate issue?  In fact the whole point (3) of the
proposal should be moved.  That issue should also discuss whether there
are any constraints on whether one top-level form is processed before
the next top-level form is read, in case the one form changes package,
changes readtable, defines a read-syntax, or defines a structure used in
#S read-syntax.

Also, when you say:

  Clarify
  that all defining macros which create functional objects (including
  DEFMACRO, DEFTYPE, DEFINE-SETF-METHOD, and the complex form of
  DEFSETF, as well as DEFUN) must ensure that those functions are
  defined in the lexical environment in which the defining form is
  evaluated.

I strongly believe that MACROLET must be consistent with this, which
would be a change.  Has that been dealt with as a separate issue?  If
not, it should either be added to this issue or brought up as a
separate issue, with the interdependency noted in both writeups to
minimize the chance of an inconsistent vote.

∂14-Mar-89  1326	CL-Compiler-mailer 	issue COMPILE-FILE-SYMBOL-HANDLING, version 2
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89  13:25:58 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 556792; Tue 14-Mar-89 16:23:12 EST
Date: Tue, 14 Mar 89 16:23 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue COMPILE-FILE-SYMBOL-HANDLING, version 2
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903132312.AA02542@defun.utah.edu>
Message-ID: <19890314212313.3.MOON@EUPHRATES.SCRC.Symbolics.COM>

I favor COMPILE-FILE-SYMBOL-HANDLING:CURRENT-PACKAGE.
COMPILE-FILE-SYMBOL-HANDLING:HOME-PACKAGE seems superficially simpler,
but my experience when we tried it at MIT indicates that it does not
work very well.  Too often a symbol that had been moved from one package
to another, or had its export status changed, would be silently moved
back to its original package by loading a file.  I sort-of agree with
JonL's comment at the end of the discussion section: if we can't agree
on one solution to his issue, I think that in practice there would be
little harm to portable programs if we left it unspecified.  The issue
really affects development environments much more than it affects the
language in which portable programs are written, although it does have
some effect on that as well.

∂14-Mar-89  1340	CL-Compiler-mailer 	issue COMPILE-ENVIRONMENT-CONSISTENCY, version 4  
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89  13:40:33 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 556802; 14 Mar 89 16:37:50 EST
Date: Tue, 14 Mar 89 16:37 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue COMPILE-ENVIRONMENT-CONSISTENCY, version 4
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903132250.AA02499@defun.utah.edu>
Message-ID: <19890314213750.4.MOON@EUPHRATES.SCRC.Symbolics.COM>

All the things I didn't like in version 3 have been fixed.
I would favor COMPILE-ENVIRONMENT-CONSISTENCY:CLARIFY if one change
were made.  The proposal says:

  Except where some other behavior is explicitly stated, when
  the compiletime and runtime definitions are different, it is
  unspecified which will prevail within the compiled code.

This means that either the compiletime or the runtime definition
will prevail, but nothing else can happen.  It must also be
permissible to signal an error complaining about the discrepancy.

∂14-Mar-89  1351	CL-Compiler-mailer 	issue SAFE-CODE, version 1    
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89  13:51:31 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 556829; Tue 14-Mar-89 16:49:05 EST
Date: Tue, 14 Mar 89 16:49 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue SAFE-CODE, version 1
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131726.AA02193@defun.utah.edu>
Message-ID: <19890314214907.7.MOON@EUPHRATES.SCRC.Symbolics.COM>

I agree with SAFE-CODE:SAFETY-3.

I disagree with the usage (in the examples) of "unsafe code" to mean
"all code where the OPTIMIZE quality of SAFETY is not 3."  I believe
that "unsafe code" should mean code that is actually unsafe, not code
that an implementation is permitted to treat as unsafe if it wishes.  I
believe there should be no portable way to write unsafe code.  This is
only a matter of wording.  If we need a shorter term for "all code where
the OPTIMIZE quality of SAFETY is not 3" I would suggest "potentially
unsafe code."

∂14-Mar-89  1357	CL-Compiler-mailer 	issue COMPILER-VERBOSITY, version 6
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89  13:56:56 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 556842; Tue 14-Mar-89 16:54:22 EST
Date: Tue, 14 Mar 89 16:54 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue COMPILER-VERBOSITY, version 6
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131546.AA02078@defun.utah.edu>
Message-ID: <19890314215423.8.MOON@EUPHRATES.SCRC.Symbolics.COM>

I like COMPILER-VERBOSITY:LIKE-LOAD.  This fixes all of the
problems I had with the version 5 proposal.

Like BarMar, I question the need for either of :PRINT and :VERBOSE in
either of LOAD and COMPILE-FILE.  But that might be my own cultural
bias, due to the type of systems I use, where it's easy to see what's
going on inside.  If other people claim they need these, I'll believe
them.

∂14-Mar-89  1419	X3J13-mailer 	Issue: ERROR-NOT-HANDLED (Version 1)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 14 Mar 89  14:19:42 PST
Received: from Semillon.ms by ArpaGateway.ms ; 14 MAR 89 14:03:50 PST
Date: 14 Mar 89 14:02 PST
From: masinter.pa@Xerox.COM
to: X3J13@sail.stanford.edu
Subject: Issue: ERROR-NOT-HANDLED (Version 1)
reply-to: cl-cleanup@sail.stanford.edu
line-fold: NO
Message-ID: <890314-140350-1917@Xerox>

Cleanup issues for the next meeting will be tricking out over the next 
week.


This issue was distributed prior to the October 1988 meeting,
but not voted on. 


!
Issue:        ERROR-NOT-HANDLED
References:   Interactive Condition Handling (Condition System, Rev 18, p19)
Category:     CLARIFICATION/CHANGE
Edit history: 25-Sep-88, Version 1 by Pitman

Problem Description:

  For delivery purposes, some implementations will want to leave out
  major sections of runtime support in programs that do not require
  them. The debugger is one such section.

  However, since ERROR may be called implicitly by a number of Common
  Lisp built-in functions, and since the condition system as currently
  described insists that the interactive debugger be entered if a
  condition is unhandled, the interactive debugger must be retained in
  a saved image of any program that might signal an error unless the
  compiler can prove that the error will never go unhandled. This
  may be undesirable in some cases and may cause unnecessary bloating
  of the saved image.

Proposal (ERROR-NOT-HANDLED:PERMIT-TERMINATION):

  Permit implementors to designate an implementation-specific mechanism
  for asking that unhandled errors cause `termination of the running
  program' rather than entry into the system's debugger.

  Implementations choosing to offer such a facility must clearly define
  the nature and scope of such program termination, since the concept
  of `program termination' is an ill-defined concept in present-day
  Common Lisp.

  Even when program termination rather than debugger entry would be
  the ultimate effect of an unhandled error, the value of 
  *DEBUGGER-HOOK* (if non-NIL) must be called to provide programmers
  the ability of customized debugging.

  All implementations must at least provide the option of a system
  debugger for use in program development.

Test Case:

  (ERROR "Foo"), if unhandled, must now enter the debugger.

  Under this proposal, it might also `terminate program execution'
  in implementations which choose to provide such a facility and to
  clearly define that concept.

Rationale:

  Although technically an incompatible change, we're dealing at
  the very edge of what the user can expect from the system. Once
  an error is signalled and not handled, we're in the domain of 
  implementation-dependent effect anyway.

Current Practice:

  Probably no one does this yet.

Cost to Implementors:

  None. This change is upward compatible with existing implementations.

Cost to Users:

  None.

Cost of Non-Adoption:

  Saved Lisp images might be forced to be gratuitously larger than
  they need to be in some implementations.

Benefits:

  Addressing this issue will make Lisp more able to compete with
  other languages which permit small saved images to result from
  small user programs.

Aesthetics:

  No significant impact.

Discussion:

  This change was requested by Christian Queinnec of France
  (queinnec@inria.inria.fr). Pitman supports the change.

∂14-Mar-89  1438	CL-Compiler-mailer 	issue COMPILER-DIAGNOSTICS, version 9   
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89  14:38:21 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 556909; Tue 14-Mar-89 17:35:56 EST
Date: Tue, 14 Mar 89 17:35 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue COMPILER-DIAGNOSTICS, version 9
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131545.AA02075@defun.utah.edu>
Message-ID: <19890314223550.1.MOON@EUPHRATES.SCRC.Symbolics.COM>

I favor COMPILER-DIAGNOSTICS:USE-HANDLER, but there are two
things that I think need to be changed:

  Conditions of type WARNING may be signalled by the compiler in 
  situations where ... the compiler can determine 
  that a situation that "is an error" would result at runtime.

We don't use the term "is an error" any more, do we?  In the old
CLtL terms, I think both "is an error" and "signals an error"
situations would justify a warning.  I think this part should
be updated to the new error terminology and also should state that
all error situations justify warnings.  Of course explicit calls
to the function ERROR don't justify warnings; I don't know whether
the proposal can be phrased in such a way as to make that clear,
or whether it will have to be left to common sense.

    (3) Require COMPILE and COMPILE-FILE to handle the ABORT restart by
    aborting the smallest feasible part of the compilation.

I think this is wrong.  The only documentation of the ABORT restart
that I could find says

  The purpose of the ABORT restart is generally to allow return to the
  innermost ``command level.''

I agree with this, and I believe it means that it is wrong for any
function other than one that establishes a read-eval-print loop or
a command-level to establish an ABORT restart.  It would be useful
to have some restart that aborts a portion of the compilation, but
it should be given some other name.

∂14-Mar-89  1505	CL-Cleanup-mailer 	Issue: ERROR-NOT-HANDLED (Version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89  15:04:58 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 556941; Tue 14-Mar-89 18:02:30 EST
Date: Tue, 14 Mar 89 18:02 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: ERROR-NOT-HANDLED (Version 1)
To: cl-cleanup@sail.stanford.edu
cc: X3J13@sail.stanford.edu
In-Reply-To: <890314-140350-1917@Xerox>
Message-ID: <19890314230224.2.MOON@EUPHRATES.SCRC.Symbolics.COM>

ERROR-NOT-HANDLED:PERMIT-TERMINATION is okay with me.  I would
also support a proposal to replace "the condition system as currently
described insists that the interactive debugger be entered if a
condition is unhandled" with wording that allowed implementations
to do whatever they want, with perhaps an implementation note that
many implementations prefer an interactive debugger.

∂14-Mar-89  1544	CL-Compiler-mailer 	**DRAFT** issue SYNTACTIC-ENVIRONMENT-ACCESS (version 4)    
Received: from YUKON.SCRC.Symbolics.COM (SCRC-YUKON.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89  15:44:06 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by YUKON.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 438041; Tue 14-Mar-89 18:42:58 EST
Date: Tue, 14 Mar 89 18:41 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** issue SYNTACTIC-ENVIRONMENT-ACCESS (version 4)
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903140019.AA02631@defun.utah.edu>
Message-ID: <19890314234118.3.MOON@EUPHRATES.SCRC.Symbolics.COM>

This looks good so far.  A few comments that might help you
along with the draft:

VARIABLE-KIND should return the same second value that FUNCTION-KIND
returns.

It's a good idea to avoid the ambiguous word "may" and say "might",
"must", or "is permitted to".

I would assume that VARIABLE-TYPE is not required to return the
exact declared type specifier, but could return another type
specifier that is equivalent, or possibly another type specifier
that is a supertype.  An implementation that canonicalizes type
declarations would do this.  For example, if A was declared
(INTEGER 0 4999), VARIABLE-TYPE might return that list, another
list that was EQUAL to it but not EQ, the list (INTEGER (-1) (5000)),
the symbol FIXNUM, or perhaps something else.  Similarly OR's and
AND's might be reduced to simpler type specifiers in an implementation
dependent way.  If, on the other hand, VARIABLE-TYPE is not permitted
to do this, but must return the exact type specifier used in the
declaration, that would be okay, but should be stated explicitly.
Similar comments apply to FUNCTION-FTYPE of course.

I assume AUGMENT-ENVIRONMENT is permitted to share structure with
its env argument, although the proposal says "a copy of ENV".

The :MACRO argument to AUGMENT-ENVIRONMENT shouldn't look like the CADR
of a MACROLET special form, instead it should be a list of lists (name
function).  That is, the expander functions should be supplied in the
form of functions rather than in the form of the source text used by
MACROLET.  Your rationale argues against this but I strongly believe
that the rationale is wrong.  I wouldn't mind seeing the parsing portion
of MACROLET made available as a separate function.

No way is provided to retrieve declarations other than SPECIAL, TYPE,
FTYPE, and LEXICAL (if PROCLAIM-LEXICAL passes).  I think all
declarations should be retrievable, but OPTIMIZE declarations seem
particularly useful to retrieve in macros or optimizers that expand into
different code depending on the safety level or the speed/space
tradeoff.  The irregular structure of declarations makes retrieving
them a bit complex, but here's my suggestion:

  DECLARATION decl-type name &optional env     [Function]

  decl-type is a symbol.  The interpretation of name depends
  on decl-type.  If a declaration of that type and name is
  in force in the specified environment, it is returned, otherwise
  NIL is returned.  The following decl-types are specified,
  additional implementation-dependent types could be added:

    INLINE function-name => T or NIL
    NOTINLINE function-name => T or NIL
    IGNORE variable-name => T or NIL
    OPTIMIZE quality => integer
    DECLARATION decl-type => T or NIL

The possible interpreter implementation of COMPILER-LET I mentioned
in another message earlier today would seem to require another
keyword argument to AUGMENT-ENVIRONMENT.  Does this mean that we
have to dictate some particular interpreter implementation of
COMPILER-LET?  I'm unsure.

Symbolics Genera includes an undocumented internal macro, used
quite a bit in the implementation of the interpreter and code
analyzers, that could have been called WITH-AUGMENTED-ENVIRONMENT,
taking keywords like AUGMENT-ENVIRONMENT and also body forms,
and producing an environment with dynamic extent bound to a
variable within the body forms.  Would it be useful to have this
too, or instead of AUGMENT-ENVIRONMENT?  I'm unsure.

On SYNTACTIC-ENVIRONMENT-ACCESS:MEDIUM, my feeling today is that
this should be left out for now, even though I think we will want
something like it later, at the same time that CLOS metaobjects
go in.

Ditto for SYNTACTIC-ENVIRONMENT-ACCESS:LARGE.

∂14-Mar-89  1555	X3J13-mailer 	LETTER BALLOT -- Sun Microsystems   
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 14 Mar 89  15:55:09 PST
Received: from snail.Sun.COM (snail.Corp.Sun.COM) by Sun.COM (4.1/SMI-4.0)
	id AA21551; Tue, 14 Mar 89 15:16:32 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
	id AA11449; Tue, 14 Mar 89 15:12:40 PST
Received: by clam.sun.com (4.0/SMI-4.0)
	id AA26931; Tue, 14 Mar 89 15:16:13 PST
Date: Tue, 14 Mar 89 15:16:13 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8903142316.AA26931@clam.sun.com>
To: chapman%aitg.DEC@decwrl.dec.com
Subject: LETTER BALLOT -- Sun Microsystems
Cc: kempf%clam@Sun.COM, peck%clam@Sun.COM, sgadol%clam@Sun.COM,
        x3j13@sail.stanford.edu

This is the Sun Microsystems vote.

 ________________________________________________________________________
 Issue or section name          |   Version      |  Y   |   I   |   A   |
 ------------------------------------------------------------------------
 CUT-OFF-DATES                  |      4         |      |   I   |       |
 ------------------------------------------------------------------------
 ERROR-TERMINOLOGY              |      5         |      |   I   |       |
 ------------------------------------------------------------------------
 FONTS                          |      2         |  Y   |       |       |
 ------------------------------------------------------------------------
 TOC                            |      1         |  Y   |       |       |
 ------------------------------------------------------------------------
 Section 1.8                    |     5.8        |  Y   |       |       |
 ------------------------------------------------------------------------
 Section 2.3                    |     5.8        |  Y   |       |       |
 ------------------------------------------------------------------------
 Section 2.4                    |     5.8        |  Y   |       |       |
 ------------------------------------------------------------------------
 Section 2.5                    |     5.8        |      |       |   A   |
 ------------------------------------------------------------------------
 Section 6.1                    |     5.8        |      |   I   |       |
 ------------------------------------------------------------------------
 
Overall, I'm impressed with the work that has been done on
writing the standard, but not entirely comfortable with the process
I can see for getting from where we are to an actual standard.

CUT-OFF-DATES

I have both general and specific comments about the CUT-OFF-DATES
proposal.  The general comments first:

The cutoff dates question causes me some discomfort, and I think
that is because the proposal is not as explicit as it might be.

First, how about stating what the goal for 12/89 is?  E.g. a
draft standard approved by X3J13 and ready for release and
outside comments.

Second, as I understand it, the "final changes" dates are for
final changes from the selected reviewers for each section of
the standard, though this is not stated.

The process, as I understand it, is that a set of reviewers will
read each section (or set of tool descriptions) carefully and
submit corrections, etc..  The full committee will then vote on
these.

A proper review will need to be done by subject rather than by sections
of the alphabet.  In fact at least one person at Sun has volunteered to
work on a particular subject.  Note that Moon expects Symbolics
internal reviewers to do likewise.  To me that implies the catalog of
tools must be voted on by subject rather than alphabetically, so I
recommend reorganizing those cutoff dates and votes by subject.

Moon suggests that it will take "several months" for Symbolics
to review the draft standard, and that the availability of
the cleanup process will be important for fixing problems
in the statement of the draft standard.  I second this.

Being active in the compiler committee, I feel confident that a
well-constructed section on compilation will *not* be ready by
4/22/89.  We need to bring the compiler work to a conclusion as close
to that date as we can, though, even if all is not perfect.  The full
committee needs to help make this happen.  (Thanks especially to David
Moon for his recent input.)

ERROR-TERMINOLOGY

The error terminology is OK, except for "consequences
are unspecified".  That concept is broken, though it
has serious defenders.  For example, Dick Gabriel says,

  "If we were to drop this term, then every time we are
  ``explicitly vague'' a valid possibility is that a fatal
  error can occur.  How is it any better to say that what happens
  when some operation happens is ``explicitly vague''."

A typical area of "explicit vagueness" is the destructive operations
on lists.  The explicit vagueness here is quite limited.  For
some operations any top level cell of certain lists may or may
not be modified.  Similar statements apply to other operations.
The consequences are far from being unspecified but harmless.
They are CONSTRAINED but meaningful.

In other situations we may say that order of certain actions
is unspecified or we may say that a side effect may or may not
occur.  (For example, numerical operations may be performed
in any of various orders.)  All of these are appropriate ways
to state a specification.

Maybe someone will make me suddenly see the light and I'll realize
how silly I've been, but so far the idea of consequences being
"unspecified but harmless" seems more like a witticism than
a useable idea.

SECTION 6.1

Under "Other Information", many of the terms are actually
type specifiers.  Wouldn't it be better to say that if a name
is the same as a type specifier, that argument must satisfy
the type specifier?

  arguments to the function -- unclear to me
  
  boolean -- I presume this are to be arguments where
             all non-NIL values are *treated* alike.
             

Note that for macros we truly specify *syntax* (at least
for some, e.g. defstruct.  For most functions we actually
give a lambda list.

p6-8, item 2b, the keyword :test-not has been flushed from
the sequence functions.

∂14-Mar-89  1610	X3J13-mailer 	Re: Issue: UNSOLICITED-MESSAGES
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 14 Mar 89  16:09:57 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK   via Janet with NIFTP
           id aa07509; 14 Mar 89 18:01 GMT
Date: Tue, 14 Mar 89 17:58:24 GMT
Message-Id: <8289.8903141758@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Issue: UNSOLICITED-MESSAGES
To: Kent M Pitman <KMP@scrc-stony-brook.arpa>, barmar@think.com
Cc: chapman <@decwrl.dec.com:chapman@aitg.dec>, x3j13@sail.stanford.edu

>     Why is this problem unique to Lisp?  Is there any wording in the C
>     standard that explicitly prohibits malloc() from causing output?  I
>     doubt it, yet I don't think they find this disturbing.
> 
> Maybe it's because C people have traditionally been willing to settle 
> for less. :-) Seriously, I think it's a clear hole in their standard.
> People would probably flame if things that weren't documented as doing
> I/O were to suddenly start doing it.

As far as I know, the C standard also doesn't say that assignment
doesn't print out "I'm doing an assignment" or, indeed, that y = 6
doesn't also assign 17 to xyzzy.  But does it need to make explicit
prohibitions?

The C standard says "In the abstract machine, all expressions are
evaluated as specified by the semantics."  Presumably there is an
implication that it doesn't do random other things.

-- Jeff

∂14-Mar-89  1629	CL-Compiler-mailer 	issue CONSTANT-COMPILABLE-TYPES, version 8   
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89  16:29:32 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 557038; Tue 14-Mar-89 19:27:03 EST
Date: Tue, 14 Mar 89 19:27 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue CONSTANT-COMPILABLE-TYPES, version 8
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131612.AA02083@defun.utah.edu>
Message-ID: <19890315002703.4.MOON@EUPHRATES.SCRC.Symbolics.COM>

I apologize in advance for the length of this message.

This is good except for a few typos and the controversial business about
functions.  I'd really like to see another round of editing to clean up
these problems before we're asked to vote on this.

I suggest moving everything having to do with functions to a
separate proposal.  What's currently in the body of the proposal for
functions does not make any sense to me.  I basically agree with the
comments from both Loosemore and Gabriel about this quoted in the
discussion section.  However, we need to be careful when we discuss this
to distinguish between a function as a constant in compiled code, and a
form whose result is a function appearing in compiled code.  The former
is `(quote ,#'(lambda ...)), the latter is `#'(lambda ...).  The meaning
of the latter is clear, of course, and a useful question would be
whether it can fully satisfy the need for functions in compiled code and
eliminate any demand for the former.

I've said this before, but I still think the proposal would be
easier to understand if it explicitly dealt separately with
  (1) relation of objects in the input of COMPILE-FILE to corresponding
  objects in the result of LOAD of the output of COMPILE-FILE.
  (2) relation of two objects in the output of a single COMPILE-FILE.
  (3) relation of two objects in the output of two different COMPILE-FILEs.
instead of smushing these together in a fuzzy way.  Look at the discussion
of uninterned symbols, for example: I found it incomprehensible.

Typos:

  For any object that
  appears in a constant, but is not supported by the language as part of
  a constant, the behavior of the compiler is unspecified; either the
  the compiler and/or loader will handle that constant (in an
  implementation-dependent manner) or the compiler will detect the
  situation and signal an error.

This says that the behavior of the compiler is unspecified and then
proceeds to specify it!

  Because hash keys can be aggregate objects and because we treat hash
  tables as unordered sets of <key, value> pairs, similarity of hash
  tables is more complex.  See under "Hash Tables", below, for the
  definition.

I have no idea how this paragraph got into the middle of the discussion
of uninterned symbols.

  References to packages are permitted in any constant.  

This sentence is redundant, or else it implies that references to some
other types are permitted in some constants but not in other constants,
which I don't think you intended.

  At load time, the package becomes the same as returned by

I don't know what it means for a package to "become".  I think
this is just fractured syntax, though.  See again my suggestion
for distinguishing the three types of similarity, which I think
indicates how to rewrite this sentence to be clear.

Under hash table:
  The table's test is unchanged also.

Unchanged from what?  I think what this was supposed to say was
that the table's test is a "basic attribute."

   Consider a hash table as an unordered set of key and
   value pairs.  Two hash tables are similar as constants
   exactly if there is a one-to-one correspondence between
   the key and value pairs of each and a one-to-one
   correspondence between the uninterned symbols of each
   such that the two keys of each corresponding pair are
   similar as constants and the two values are also similar
   as constants.  The correspondence of uninterned symbols
   must be consistent with the correspondence defined for
   the entire set of constants in the file.

This paragraph is totally garbled.  If you took out the
stuff about uninterned symbols it might make sense.

Structure, Standard-object
             <<There is a cl-cleanup issue, LOAD-OBJECTS, pending
             which proposes a mechanism for dealing with objects.>>
             For structure instances with no method defined at compile
             time for MAKE-LOAD-FORM, the slot values and the name of
             structure type (a symbol reference) are recorded by the
             compiler and reconstructed by the loader.

The text not enclosed in french quotation marks directly contradicts
the LOAD-OBJECTS proposal.  It should be removed so we don't have two
proposals trying to talk about the same thing.

This sentence in the discussion section:

  The full extension of the concept of coalescing of constants is to say
  that they can be coalesced exactly when they are similar as constants.

seems to be in the wrong document, since this issue is not about
coalescing of constants and does not otherwise mention it, except
incidentally in connection with a bug in Coral Lisp.

∂14-Mar-89  1636	CL-Compiler-mailer 	issue CONSTANT-COMPILABLE-TYPES, version 8   
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89  16:36:44 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 557048; Tue 14-Mar-89 19:34:07 EST
Date: Tue, 14 Mar 89 19:34 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue CONSTANT-COMPILABLE-TYPES, version 8
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131612.AA02083@defun.utah.edu>
Supersedes: <19890315002703.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Comments: Fix some typos in the definitions of the three concepts that I claim
          should not be smushed together.  Cris Perdue pointed out these typos
          earlier, but I forgot to fix them before sending the first copy of this
          message.
Message-ID: <19890315003408.5.MOON@EUPHRATES.SCRC.Symbolics.COM>

I apologize in advance for the length of this message.

This is good except for a few typos and the controversial business about
functions.  I'd really like to see another round of editing to clean up
these problems before we're asked to vote on this.

I suggest moving everything having to do with functions to a
separate proposal.  What's currently in the body of the proposal for
functions does not make any sense to me.  I basically agree with the
comments from both Loosemore and Gabriel about this quoted in the
discussion section.  However, we need to be careful when we discuss this
to distinguish between a function as a constant in compiled code, and a
form whose result is a function appearing in compiled code.  The former
is `(quote ,#'(lambda ...)), the latter is `#'(lambda ...).  The meaning
of the latter is clear, of course, and a useful question would be
whether it can fully satisfy the need for functions in compiled code and
eliminate any demand for the former.

I've said this before, but I still think the proposal would be
easier to understand if it explicitly dealt separately with
  (1) relation of objects in the input of COMPILE-FILE to corresponding
  objects in the result of LOAD of the output of COMPILE-FILE.
  (2) relation of two objects in the result of LOAD of the output
  of a single COMPILE-FILE.
  (3) relation of two objects in the result of LOAD of the output
  of two different COMPILE-FILEs.
instead of smushing these together in a fuzzy way.  Look at the discussion
of uninterned symbols, for example: I found it incomprehensible.

Typos:

  For any object that
  appears in a constant, but is not supported by the language as part of
  a constant, the behavior of the compiler is unspecified; either the
  the compiler and/or loader will handle that constant (in an
  implementation-dependent manner) or the compiler will detect the
  situation and signal an error.

This says that the behavior of the compiler is unspecified and then
proceeds to specify it!

  Because hash keys can be aggregate objects and because we treat hash
  tables as unordered sets of <key, value> pairs, similarity of hash
  tables is more complex.  See under "Hash Tables", below, for the
  definition.

I have no idea how this paragraph got into the middle of the discussion
of uninterned symbols.

  References to packages are permitted in any constant.  

This sentence is redundant, or else it implies that references to some
other types are permitted in some constants but not in other constants,
which I don't think you intended.

  At load time, the package becomes the same as returned by

I don't know what it means for a package to "become".  I think
this is just fractured syntax, though.  See again my suggestion
for distinguishing the three types of similarity, which I think
indicates how to rewrite this sentence to be clear.

Under hash table:
  The table's test is unchanged also.

Unchanged from what?  I think what this was supposed to say was
that the table's test is a "basic attribute."

   Consider a hash table as an unordered set of key and
   value pairs.  Two hash tables are similar as constants
   exactly if there is a one-to-one correspondence between
   the key and value pairs of each and a one-to-one
   correspondence between the uninterned symbols of each
   such that the two keys of each corresponding pair are
   similar as constants and the two values are also similar
   as constants.  The correspondence of uninterned symbols
   must be consistent with the correspondence defined for
   the entire set of constants in the file.

This paragraph is totally garbled.  If you took out the
stuff about uninterned symbols it might make sense.

Structure, Standard-object
             <<There is a cl-cleanup issue, LOAD-OBJECTS, pending
             which proposes a mechanism for dealing with objects.>>
             For structure instances with no method defined at compile
             time for MAKE-LOAD-FORM, the slot values and the name of
             structure type (a symbol reference) are recorded by the
             compiler and reconstructed by the loader.

The text not enclosed in french quotation marks directly contradicts
the LOAD-OBJECTS proposal.  It should be removed so we don't have two
proposals trying to talk about the same thing.

This sentence in the discussion section:

  The full extension of the concept of coalescing of constants is to say
  that they can be coalesced exactly when they are similar as constants.

seems to be in the wrong document, since this issue is not about
coalescing of constants and does not otherwise mention it, except
incidentally in connection with a bug in Coral Lisp.

∂14-Mar-89  1651	CL-Compiler-mailer 	issue QUOTE-SEMANTICS, version 2   
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89  16:51:17 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 557056; Tue 14-Mar-89 19:48:51 EST
Date: Tue, 14 Mar 89 19:48 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue QUOTE-SEMANTICS, version 2
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131721.AA02184@defun.utah.edu>
Message-ID: <19890315004852.6.MOON@EUPHRATES.SCRC.Symbolics.COM>

I favor QUOTE-SEMANTICS:NO-COPYING for two reasons: 
(1) it's clearly more aesthetic.
(2) I can't support either of the other two proposals because they use
the words "copying" and "coalescing" without defining their meaning.

My position could be changed to
QUOTE-SEMANTICS:COPYING-ALLOWED-BUT-NO-CONSTRAINTS by adding definitions
for those two words and by a strong argument that the implementation
cost of QUOTE-SEMANTICS:NO-COPYING is too high, since I believe to some
extent JonL's argument (quoted in the discussion section) that EQL of
(some types of) constants does not matter.

I can't imagine any argument that would convince me to
support QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE.  I believe Kent's
arguments against it (quoted in the discussion section).

∂14-Mar-89  1700	CL-Compiler-mailer 	issue MACRO-CACHING, version 2
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89  17:00:30 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 557059; Tue 14-Mar-89 19:57:55 EST
Date: Tue, 14 Mar 89 19:57 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue MACRO-CACHING, version 2
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131647.AA02151@defun.utah.edu>
Message-ID: <19890315005756.7.MOON@EUPHRATES.SCRC.Symbolics.COM>

I support MACRO-CACHING:DISALLOW.  I'd like to point out that the
"correct" way to do macro caching is not mentioned anywhere in this
writeup.  Perhaps that was justified because there is no portable way to
do it (an implementation can do it, but a user cannot), however I think
omitting it leaves a false impression.

The "correct" way to do macro caching is via a table inside the lexical
environment structure, which has very different properties from a table
keyed by the lexical environment structure, mentioned in the writeup.

I think a shorter writeup might be better.  It could simply say that
there is no correct portable way to use *MACROEXPANSION-HOOK* to cache
macro expansions, and that there is no requirement that an implementation
call the macro expansion function more than once for a given form
and lexical environment.  This prohibits the incorrect user code discussed
at some length in the existing writeup, leaves implementations license
to do macro caching correctly, and avoids a lot of unnecessary detail.

∂14-Mar-89  1704	CL-Compiler-mailer 	issue LOAD-TIME-EVAL, version 11   
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89  17:04:49 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 557069; 14 Mar 89 20:02:04 EST
Date: Tue, 14 Mar 89 20:02 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue LOAD-TIME-EVAL, version 11
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131631.AA02140@defun.utah.edu>
Message-ID: <19890315010205.8.MOON@EUPHRATES.SCRC.Symbolics.COM>

I like LOAD-TIME-EVAL:R**3-NEW-SPECIAL-FORM.

∂14-Mar-89  1722	CL-Compiler-mailer 	issue CONSTANT-COLLAPSING, version 5    
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89  17:21:52 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 557083; Tue 14-Mar-89 20:10:42 EST
Date: Tue, 14 Mar 89 20:10 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue CONSTANT-COLLAPSING, version 5
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131622.AA02093@defun.utah.edu>
Message-ID: <19890315011043.9.MOON@EUPHRATES.SCRC.Symbolics.COM>

The proposal says:

  State the an implementation is permitted to coalesce constants
  appearing in code to be compiled if they are equivalent under the
  relationship defined in proposal CONSTANT-COMPILABLE-TYPES:SPECIFY.

I can't understand what this means.  The referenced proposal uses
the word "similar", not "equivalent".  I'd support this alternate
wording:

  Suppose that A and B are two objects used as quoted constants in the
  input to COMPILE-FILE, and that A' and B' are the corresponding
  objects used as constants in the result of loading the output of
  that COMPILE-FILE.  If A' is similar as a constant to both A and B,
  then it is valid for A' and B' to be EQL even if A and B are not EQL.

This may still be too vague, since "objects in the input to
COMPILE-FILE" means not in the input text file, which doesn't contain
objects, but in the result of applying READ to the input file, and since
"corresponding objects" is not defined.

∂14-Mar-89  1722	CL-Compiler-mailer 	issue CONSTANT-CIRCULAR-COMPILATION, version 7    
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89  17:21:59 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 557096; Tue 14-Mar-89 20:15:39 EST
Date: Tue, 14 Mar 89 20:15 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue CONSTANT-CIRCULAR-COMPILATION, version 7
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131619.AA02090@defun.utah.edu>
Message-ID: <19890315011539.0.MOON@EUPHRATES.SCRC.Symbolics.COM>

I favor CONSTANT-CIRCULAR-COMPILATION:YES except that all references to
EQ should be changed to EQL.  There is no reason to require
implementations to be careful about EQ of numbers and characters.

∂14-Mar-89  1731	X3J13-mailer 	Issue: GENSYM-NAME-STICKINESS (Version 1)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 14 Mar 89  17:31:12 PST
Received: from Semillon.ms by ArpaGateway.ms ; 14 MAR 89 14:57:16 PST
Date: 14 Mar 89 14:56 PST
From: masinter.pa@Xerox.COM
Subject: Issue: GENSYM-NAME-STICKINESS (Version 1)
To: x3j13@SAIL.Stanford.EDU
reply-to: cl-cleanup@sail.stanford.edu
line-fold: no
Message-ID: <890314-145716-2049@Xerox>


Additional Comments include:

"... it's ... late to consider things like this ..."
"YAY!!!    This is what "cleanup" is for. Go For It! "
"Sounds like a good idea to me."

!
Issue:        GENSYM-NAME-STICKINESS
Forum:	      Cleanup
References:   GENSYM (p169)
Category:     CHANGE
Edit history: 14-Feb-89, Version 1 by Pitman

Problem Description:

  Many people avoid use of the argument to GENSYM because the argument
  is `sticky' and such stickiness can lead to confusion. The problem is
  that if any application (usually a macro) uses the gensym argument at
  all, then all applications are forced to. If they do not, they risk
  finding that the `helpful' argument supplied in some previous call will
  be harmful to them.

Proposal (GENSYM-NAME-STICKINESS:WASH-HANDS):

  Define that if an optional argument is given to GENSYM, it does NOT
  have a side-effect on GENSYM's internal state.

Rationale:

  Conscientious programmers are forced now to write their own GENSYM
  lookalikes because they know the system's GENSYM has an invasive
  effect. This defeats the primary intended function of GENSYM, which
  is to satisfy the most common idiomatic use of MAKE-SYMBOL.

  The stickiness of the GENSYM prefix was an attempt to be gratuitously
  compatible with Maclisp, at the expense of good programming pratice.

  Users who need the old behavior of GENSYM can trivially implement
  that behavior using MAKE-SYMBOL.

Test Case:

  (CHAR-EQUAL (CHAR (SYMBOL-NAME (SECOND (LIST (GENSYM "A") (GENSYM)))) 0)
	      #\G)
  => NIL ;under CLtL
  => T   ;under this proposal

Current Practice:

  Symbolics Cloe and Genera are compatible with CLtL, so this would be an
  incompatible change.

Cost to Implementors:

  Very small.

Cost to Users:

  Most uses of GENSYM do not depend on the stickiness of the name, so the
  change would be compatible. In some cases, the change would be an
  improvement. Even in the worst case where someone depends on stickiness,
  it's extremely straightforward to write the couple of lines of code to
  produce an application based on MAKE-SYMBOL that is at least as flexible
  as GENSYM, and often moreso.

Cost of Non-Adoption:

  Good programmers would avoid using the argument to GENSYM (or using 
  GENSYM altogether) in many situations where they ought not have to.

Benefits:

  Gensyms which appear to convey information through their name would not
  accidentally pop out and cause confusion in places where they oughtn't.

Aesthetics:

  Unnecessary global state changes are hard to reason about. This would 
  be a small simplification.

Discussion:

  Pitman claims to have written a non-sticky GENSYM function for nearly
  every one of the dozen or so large systems that he's written or worked
  on in the last decade in order to get around the stated problem.
  Others have suggested similar experience.

  Pitman supports the proposal. 



     ----- End Forwarded Messages -----

∂14-Mar-89  1730	CL-Compiler-mailer 	issue COMPILED-FUNCTION-REQUIREMENTS, version 4   
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Mar 89  17:29:45 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 557112; 14 Mar 89 20:27:21 EST
Date: Tue, 14 Mar 89 20:27 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue COMPILED-FUNCTION-REQUIREMENTS, version 4
To: cl-compiler@sail.stanford.edu
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903131544.AA02070@defun.utah.edu>
Message-ID: <19890315012722.1.MOON@EUPHRATES.SCRC.Symbolics.COM>

I much prefer the option FLUSH, which was in version 2 but has been
removed.  That option was to remove the COMPILED-FUNCTION type.
This type has no portable meaning and never should have existed.

I have no objection to the proposed specification of what the COMPILE
and COMPILE-FILE functions do, but it should be decoupled from the
COMPILED-FUNCTION type and discussed under the rubric of those two
functions.  The parts about COMPILER-LET and EVAL-WHEN can probably be
removed (assuming the COMPILER-LET-CONFUSION proposal that eliminates
the possibility of COMPILER-LET binding any variables at run time
passes, and the EVAL-WHEN-NON-TOP-LEVEL proposal passes) since they are
redundant; there is never any interpeter/compiler difference for
COMPILER-LET or EVAL-WHEN any more.

∂14-Mar-89  1731	X3J13-mailer 	Issue: COERCE-INCOMPLETE (Version 3)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 14 Mar 89  17:31:00 PST
Received: from Semillon.ms by ArpaGateway.ms ; 14 MAR 89 14:29:58 PST
Date: 14 Mar 89 14:24 PST
From: masinter.pa@Xerox.COM
Subject: Issue: COERCE-INCOMPLETE (Version 3)
To: X3J13@sail.stanford.edu
reply-to: cl-cleanup@sail.stanford.edu
line-fold: no
Message-ID: <890314-142958-1976@Xerox>

There are a couple of "additional comments" on the proposal
at the end.
!
Issue:		 COERCE-INCOMPLETE
Reference:	 COERCE (p50)
Category:	 ADDITION/CHANGE
Edit history:	 Version 1 of COERCE-INCOMPLETE, 26-Feb-88 by M. Ida
		 Version 1 of COERCE-FROM-TYPE,  20-Jun-88 by Pitman
		 Version 2 of COERCE-INCOMPLETE, 21-Nov-88 by Pitman
		  (consolidate previous two proposals)
		 Version 3 of COERCE-INCOMPLETE, 07-Mar-89 by Pitman
		  (eliminate unpopular proposal, two new options)

Problem Description:

  COERCE is difficult to extend because ambiguities arise about the
  source type of the coercion.

  For example, if the symbol STRING were permitted as a second argument
  to coerce, as in (COERCE NIL 'STRING), there would be two posssible
  return values: "" or "NIL". The choice would be arbitrary and would
  have to be specified by the documentation. No matter which was chosen,
  it would probably turn out to be a problem for some applications at
  some times.

  Another example is (COERCE (CHAR-CODE #\A) 'STRING). This might
  return the same as (FORMAT NIL "~D" (CHAR-CODE #\A)) -- "65" in
  most ASCII-based implementations -- or it might return "A". Again,
  the choice would be arbitrary.

  There is clear desire on the part of the user community to lift some of
  the existing restrictions on arguments to COERCE, but because of legitimate
  concerns about ambiguities, the Common Lisp designers have thus far
  refused to do so.

  Unfortunately, the failure of COERCE to handle these cases means it is
  very difficult to learn to use COERCE. And the fact that COERCE is not
  easily learned contributes to difficulty in learning Common Lisp because
  instead of a single coercion operator with general purpose semantics, a
  number of very special purpose coercion operators must be learned instead.

  Some middle ground needs to be found, which neither compromises the
  clear semantics and portable nature of COERCE nor complicates COERCE
  in a way that makes it unlearnable.

  Also, some people have expressed a desire for COERCE to be more 
  `symmetric.' Usually they seem to mean that they want it to be the case
  that if (COERCE x y) works, then (COERCE (COERCE x y) (TYPE-OF x)) 
  should also work. Although this is not an essential desire, it would
  certainly be nice to achieve.
 
Proposal (COERCE-INCOMPLETE:LIMITED-ARBITRARY-EXTENSION):

  Define COERCE to accept the following equivalences:

   1. (COERCE x 'STRING)    == (STRING x)
   2. (COERCE x 'PATHNAME)  == (PATHNAME x)
   3. (COERCE x 'RATIONAL)  == (RATIONAL x)

  Clarify that

   4. (COERCE x 'FLOAT)     == (FLOAT x)

  Rationale:

    Many users think of STRING, for example, as ``the way to coerce
    something to a string'' and are baffled why COERCE and STRING
    disagree on how to do this.

    Such users think that if there's a moral battle to be waged
    over how to coerce an object to a STRING, the battle has already
    been lost by defining the STRING function -- that whatever
    decision is made for STRING must also apply to COERCE for the
    sake of simplicity.
 
    Similar arguments can be made for PATHNAME, FLOAT, and RATIONAL.

Proposal (COERCE-INCOMPLETE:DEPRECATE):

  Deprecate COERCE.

  Rationale:

    COERCE is not functionally necessary -- no operation that it does
    cannot be done in some other way.  As such, it is basically just
    a matter of syntactic convenience, and perhaps isn't worth having
    around if it will be the subject of endless debate.  Deprecating
    it would allow us to declare this issue a `dead end' and focus our
    attention on matters of greater substance.

Current Practice:

  Presumably No one implements either of the proposals at this time,
  since none are compatible with CLtL.

Cost to Implementors:

  COERCE: Small to moderate.

  DEPRECATE: None.

Cost to Users:

  COERCE: This is an incompatible change. (COERCE 'NIL 'STRING) => ""
    but (STRING NIL) => "NIL".  How many applications are impacted by
    this change is not clear. It would be straightforward to shadow
    COERCE with an alternate definition that did the old thing in
    cases where people were worried. Once such cases have been 
    identified, rewriting 
     (COERCE X 'STRING)
    as
     (IF X (COERCE X 'STRING) "")
    will suffice in most cases.

  DEPRECATE: No immediate work would be needed, although many maintained
    applications would get upgraded in order to use the primitives that
    are `in vogue.'

Cost of Non-Adoption:

  People will continue to see and debate the issues alluded to in
  the Problem Description.

Benefits:

  The cost of Non-Adoption will be avoided.

Aesthetics:

  COERCE: Many people will probably see the idea of making
    COERCE consistent with STRING, PATHNAME, FLOAT, and
    RATIONAL as a clear improvement -- possibly outweighing
    the costs of both an incompatible change and a decision
    to arbitrarily favor one treatment over the other.

  DEPRECATE: Some may take the deprecation of COERCE as an
    aesthetic improvement because it eliminates the need to
    debate this issue further. Others may see the 
    ``de-centralization'' of coercion as a step backward.

Discussion:

  Pitman supports COERCE-INCOMPLETE:LIMITED-ARBITRARY-EXTENSION.
  Hopefully Moon and Masinter support it, too, since it's
  basically patterned after a bunch of mail they were sending
  back and forth.

  A proposal to extend COERCE to permit a ``view type'' argument
  was considered and rejected as too extreme to consider seriously
  in the timeframe available.

  Pierson suggests that COERCE ought to be a candidate for
  generic function status.

  Pitman thinks that making [two-argument] COERCE generic would
  be a -very- bad idea  but believes that his earlier proposal
  involving a third `view type' argument might be able to 
  accomodate such extension.

!
Additional comments

I agree that this is ready to send out.  The thing about
COERCE-INCOMPLETE:LIMITED-ARBITRARY-EXTENSION that strikes fear
into my heart is that it wipes out CLtL's simple statement that
any sequence type may be converted to any other sequence type,
and starts people asking questions like does
(coerce nil '(vector character)) => "" or "NIL"?

This concern is not reflected at all in the writeup.

I agree that this is ready to send out but I'm inclined to vote
no on both proposals and keep the (unsatisfactory) status quo.


-----  -----

I believe that any change to the status quo is incomplete without
providing a coercion mechanism whose "viewpoint" is that of a sequence.
That is effectively what the current COERCE is, overloaded with those
types which do not conflict with SEQUENCE.

Because of the problem of differing viewpoints, I'm inclined to think
that COERCE should be shrunk down to only being a sequence coercion
function, and all other coercions should be handled by the appropriate
functions.


-----  -----

∂15-Mar-89  0520	X3J13-mailer 	Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 15 Mar 89  05:19:57 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 15 MAR 89 05:14:05 PST
Date: 15 Mar 89 05:13 PST
From: masinter.pa@Xerox.COM
to: X3J13@Sail.stanford.edu
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
reply-to: cl-cleanup@sail.stanford.edu
line-fold: NO
Message-ID: <890315-051405-3472@Xerox>

At the January '89 meeting, Version 4 of this issue was amended,
and then accepted.

We think there were some wording problems with the amendment,
in that it ended up not saying what we think was intended.
The amendment made some meaningful programs have undefined
behavior, and left the meaning of SIMPLE-ARRAY unclear.

After a good deal of work by the members of the cleanup committee,
we've arrived at the following version, which we would like
to submit to you for consideration as to whether it more
properly reflects the intent of the group.

!
Issue:        ADJUST-ARRAY-NOT-ADJUSTABLE
References:   ADJUST-ARRAY (p297), ADJUSTABLE-ARRAY-P (p293),
              MAKE-ARRAY (pp286-289), simple arrays (p28, 289)
Category:     CLARIFICATION
Edit history: 22-Apr-87, Version 1 by Pitman
              15-Nov-88, Versions 2a,2b,2c by Pitman
              02-Dec-88, Version 3 by Pitman
              11-Jan-89, Version 4 by Pitman
              16-Jan-89, Version 5, by Gabriel.  Amended at the meeting to shorten.
              23-Jan-89, Version 6, by Moon.  Shorten without the bug introduced
                        by the amendment, add clarification of SIMPLE-ARRAY type.
	      15-Feb-89, Version 7, by Pitman. Minor changes per comments from
			RPG and Dalton.
	      11-Mar-89, Version 8, by Pitman. Change category, add endorsements.

Problem Description:

  The description of the :ADJUSTABLE option to MAKE-ARRAY on p288
  says that ``the argument, if specified and not NIL, indicates that
  it must be possible to alter the array's size dynamically after
  it is created. This argument defaults to NIL.''

  The description of the :ADJUSTABLE option does not say what 
  MAKE-ARRAY will do if the argument is unsupplied or explicitly NIL.

  The description of ADJUSTABLE-ARRAY-P on p293 says that it is
  true ``if the argument (which must be an array) is adjustable, and
  otherwise false.'' However, the description of MAKE-ARRAY makes
  it clear that this is not necessarily the same as asking if
  the array was created with :ADJUSTABLE T. If ADJUSTABLE-ARRAY-P
  returns NIL, you know that :ADJUSTABLE NIL was supplied (or no
  :ADJUSTABLE option was supplied), but if ADJUSTABLE-ARRAY-P returns
  T, then there is no information about whether :ADJUSTABLE was used.

  The description of ADJUST-ARRAY on pp297-298 says that it is
  ``not permitted to call ADJUST-ARRAY on an array that was not
  created with the :ADJUSTABLE option.'' This is inconsistent with
  ADJUSTABLE-ARRAY-P.
  
  A problem which comes up in practice is that some programmers
  expect runtime error checking if they have done
  (MAKE-ARRAY ... :ADJUSTABLE NIL) and they later try to adjust
  the array using ADJUST-ARRAY.

  The definition of the SIMPLE-ARRAY type and its subtypes needs
  clarification of its relationship to adjustability.


Proposal (ADJUST-ARRAY-NOT-ADJUSTABLE:CLARIFY):

  1. ADJUSTABLE-ARRAY-P is true of all arrays created with a true
  :ADJUSTABLE option to MAKE-ARRAY.  Whether ADJUSTABLE-ARRAY-P is
  true of some other arrays is unspecified.
 
  2. If MAKE-ARRAY is called with the :ADJUSTABLE, :FILL-POINTER, 
  and :DISPLACED-TO arguments each either unspecified or false, the
  resulting array is a simple array.  (This just repeats what CLtL
  says on page 289, it's here to aid in understanding the next point.)
      
  3. If MAKE-ARRAY is called with one or more of the :ADJUSTABLE,
  :FILL-POINTER, or :DISPLACED-TO arguments true, whether the
  resulting array is simple is unspecified.
      
  4. ADJUST-ARRAY ``should signal'' an error if ADJUSTABLE-ARRAY-P
  of its first argument is false.  ADJUST-ARRAY must not signal an
  `array not adjustable' error if ADJUSTABLE-ARRAY-P of its first
  argument is true.

  5. The value of ADJUSTABLE-ARRAY-P on a simple array is unspecified.

  Note: ``should signal'' is taken from the new error terminology.
  It means that in ``safe code'' (code compiled with highest safety)
  an error must be signalled, but that in unsafe code (code not compiled
  with highest safety), an error might or might not be signalled.

Clarifications and Logical Consequences:

  a. Whether an array can be both simple and adjustable is unspecified.

  b. There is no specified way to create an array for which ADJUSTABLE-ARRAY-P
     definitely returns NIL.

  c. There is no specified way to create an array that is non-simple.

  d. This legitimizes ADJUSTABLE-ARRAY-P as an appropriate predicate to
     determine whether ADJUST-ARRAY will reliably succeed.

  e. If ADJUST-ARRAY is invoked on an array that was created without
     supplying :ADJUSTABLE true, an `array not adjustable' error
     ``should be signalled'' unless ADJUSTABLE-ARRAY-P returns true on
     that array (in which case it must not signal an `array not adjustable'
     error).

Rationale:

  This effectively makes the status quo explicit.  This preserves the
  raison d'etre of simple arrays, which is to provide a portable interface
  to implementation-dependent specialized arrays that trade decreased
  functionality for faster access.

  Specifying the points left unspecified (requiring all simple arrays to be
  non-adjustable and all adjustable arrays to be non-simple) would require
  large changes to some implementations and would be of little benefit to
  users, merely making one kind of nonconforming program fail in all
  implementations instead of failing only in some implementations. The 
  argument here is not that the error checking would not be useful for
  developers of portable code, but only that the cost of introducing that
  error checking would be exceedingly high for some implementations.

  Users need to know that certain arrays are simple, so they can put in
  declarations and get higher performance, but users have no need to be
  able to create arrays that are definitely non-simple (for lower
  performance) or definitely non-adjustable (to cause errors).

Examples:

  1. The following program is conforming.  It is unspecified which branch
  of the IF it follows.
  
    (defun double (a)
       (if (adjustable-array-p a)
           (adjust-array a (* (length a) 2))
           (let ((new (make-array (* (length a) 2))))
             (replace new a :end1 (length a))
             new)))
  
    (double (make-array 30))

  2. The following program is conforming.  In no implementation is the
  type declaration violated.

    (let ((a (make-array 100)))
      (declare (simple-array a))
      (frob a))


Current Practice:

  Probably everyone is compatible with this proposal. 

  Symbolics Genera makes :ADJUSTABLE NIL arrays adjustable in most cases,
  and ignores adjustability in deciding whether an array is simple,
  and is compatible with this proposal.

  Lucid, IIM, and Symbolics Cloe make :ADJUSTABLE NIL arrays non-adjustable
  in all cases, and make all arrays non-simple unless the Common Lisp
  language requires them to be simple, and are compatible with this proposal.

Cost to Implementors:

  It's in principle possible that some implementation would have to change,
  but in practice there are no known implementations that would have to change.

Cost to Users:

  None. This is a fully compatible change from the user's standpoint.

Benefits:

  Users would know what to expect.

Non-Benefits:

  Users who expect adjusting arrays created with :ADJUSTABLE NIL to signal
  an error would not get the desired error checking.

Aesthetics:

  Most people believe the status quo is unaesthetic.  Having an aspect of
  the language explicitly unspecified is more aesthetic than having it
  implicitly unspecified on account of vague or inconsistent documentation.

Discussion:

  Pitman, Moon, Gabriel, and Steele support this amended proposal.

  MACSYMA ran into portability problems due to the status quo.
  If the issue had been documented, that would have helped.
  Encouraging implementations that are able to at least make
  (MAKE-ARRAY ... :ADJUSTABLE NIL) create non-adjustable arrays
  where possible would help, too.

  We considered proposals to incompatibly change this primitive in a
  variety of ways, but the community was very split with strong proponents
  and opponents of each alternate proposal.

  The overriding concern driving this proposal is that Symbolics 
  has asserted that most of the other really interesting proposals would
  likely involve a sizable cost to implementors (and their installed bases)
  to implement what were judged by some as gratuitous changes from the
  status quo.

  Pitman wishes some of the other proposals were economically feasible to
  pursue but reluctantly agrees that maintaining (and clearly documenting)
  the status quo is probably the most reasonable avenue left to us.

∂15-Mar-89  0622	X3J13-mailer 	BASE-CHARACTER  
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 15 Mar 89  06:22:19 PST
Received: from Semillon.ms by ArpaGateway.ms ; 15 MAR 89 06:09:24 PST
Date: 15 Mar 89 06:07 PST
From: masinter.pa@Xerox.COM
Subject: BASE-CHARACTER
To: CL-Characters@SAIL.STANFORD.EDU
cc: X3J13@SAIL.STANFORD.EDU
Message-ID: <890315-060924-3563@Xerox>

There were a couple of points that were only tersly alluded to in my note
on the character proposal.

BASE-CHARACTER

I think most of the confusions and problems with BASE-CHARACTER in the
proposal result from its definition in terms of the 'natural' encoding of
an implementation.


I think defining BASE-CHARACTER exactly as

(UPGRADED-ARRAY-ELEMENT-TYPE 'STANDARD-CHAR)

has all of the right properties. (Recall that UPGRADED-ARRAY-ELEMENT-TYPE
was added by the (passed) proposal in ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS.)
This definition is unambiguous and shows the relationship between the
string encoding and array upgrading strategies of the implementation and
the important character types. It ensures STANDARD-CHAR is a subtype of
BASE-CHARACTER. 

Whether a character is "base" really only depends on the way that an
implementation represents strings, and not any other properties of the
implementation or the host operating system. Imagine two implementations on
a Unix machine, one of which encodes all strings as 16-bit characters, and
another which has two kinds of strings: 8-bit strings and 16-bit strings.
In the first implementation, the BASE-CHARACTER is CHARACTER: there's only
one kind of string. In the second implementation, the BASE-CHARACTER would
be those that could be stored in an 8-bit string, and it would be a proper
sub-type of CHARACTER.

To make this change requires leaving STANDARD-CHAR in the standard and then
merely defining BASE-CHARACTER in terms of it. Clearly BASE-STRING, if such
a name is necessary, would then just be a shorthand for (VECTOR
BASE-CHARACTER) with all the semantics implied by the array-element-type
proposals. 

∂15-Mar-89  0636	X3J13-mailer 	Issue IN-PACKAGE-FUNCTIONALITY (Version 8)    
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 15 Mar 89  06:35:51 PST
Received: from Semillon.ms by ArpaGateway.ms ; 15 MAR 89 06:27:41 PST
Date: 15 Mar 89 06:27 PST
From: masinter.pa@Xerox.COM
Subject: Issue IN-PACKAGE-FUNCTIONALITY (Version 8)
To: X3J13@sail.stanford.edu
reply-to: cl-cleanup@sail.stanford.edu
line-fold: NO
Message-ID: <890315-062741-3597@Xerox>

Version 4 of this issue (with only a version of
the SELECT-ONLY proposal) was discussed and tabled
at the last meeting. 

This version includes two proposals; NEW-MACRO 
(favored by many members of the cleanup committee)
and a new version of SELECT-ONLY.

!

Issue:          IN-PACKAGE-FUNCTIONALITY
References:     IN-PACKAGE (p182-183)
Category:       CHANGE
Edit history:   07-Jul-88, Version 1 by Pitman
                 7-Oct-88, Version 2 by Masinter (discussion)
                 8-Dec-88, Version 3 by Masinter
                12-Dec-88, Version 4 by Masinter
                20-Jan-89, Version 5 by Loosemore
                30-Jan-89, Version 6 by Loosemore
                10-Mar-89, Version 7 by Loosemore
                15-Mar-89, Version 8 by Masinter 
						(add back SELECT-ONLY)

Related-Issues: DEFPACKAGE (passed)
		COMPILE-FILE-SYMBOL-HANDLING

Problem Description:

  There are two typical uses for IN-PACKAGE -- to define/create a package
  and to select a package. The fact that these two purposes have been
  given to the same function has led to reduced error checking.

  A more general problem is that the "Put In Seven Extremely Randoms" 
  convention described in CLtL is now recognized by many people as being
  unsatisfactory for both package definition and package selection.
  The DEFPACKAGE macro provides a much cleaner mechanism for package
  definition, but there is still a need for a convenient way to select
  a package that has well-defined compilation semantics.


Proposal (IN-PACKAGE-FUNCTIONALITY:NEW-MACRO):

  Add a new macro:

    SELECT-PACKAGE name						[macro]

    This macro causes *PACKAGE* to be set to the package named NAME,
    which must be a symbol or string.  An error is signalled if the
    package does not already exist.  Everything this macro does is also
    performed at compile time if the call appears at top-level.

  Remove the function IN-PACKAGE from the standard.

  Remove the second paragraph of section 11.7 in CLtL.  (This includes
  the requirement for special compile-time treatment of the various
  package functions.)


  Rationale:

    This could allow improved error checking and modularity, with only
    minimal loss of functionality.

    The rationale for proposing SELECT-PACKAGE as a replacement for
    IN-PACKAGE, rather than simply changing IN-PACKAGE to have this 
    behavior, is that such an incompatible change would be confusing to
    many people, and would make it more difficult to detect obsolete
    usages.  There is nothing in this proposal that would prevent
    implementations from continuing to provide IN-PACKAGE as an extension.

    Making SELECT-PACKAGE a macro rather than a function means that there
    is no need to require COMPILE-FILE to handle it specially.  Since
    DEFPACKAGE is also defined to side-effect the compilation environment,
    there is no need to require any of the package functions to be treated
    specially by the compiler.

    The language in section 11.7 of CLtL puts the burden on
    implementations of ensuring that all symbols in a file which is
    compiled and loaded end up in the same package that they would if the
    source file were loaded interpretively.  No implementation can
    possibly meet this requirement because, in general, the runtime
    behavior of the program cannot be predicted by the compiler.

  Current Practice:

    Probably no one implements this behavior exactly since it's an 
    incompatible change to CLtL.

  Cost to Implementors:

    The SELECT-PACKAGE macro can be implemented trivially by using 
    EVAL-WHEN in its expansion:

    (defmacro select-package (name)
        `(eval-when (eval compile load)
	     (setq *package*
	           (or (find-package ',name)
		       (error "Package ~s does not exist." ',name)))))

    The changes required to COMPILE-FILE to remove the magic treatment
    of the package functions are also likely to be small.

  Cost to Users:

    In most cases, minor syntactic changes to some files would be
    necessary.  Programmers that are now using the "Put In Seven
    Extremely Randoms" convention will probably find it straightforward
    to convert their code to do a DEFPACKAGE followed by a 
    SELECT-PACKAGE.

  Cost of Non-Adoption:

    The specification of COMPILE-FILE will be much more difficult to
    understand.

    The standard will require compilers to solve the halting problem.

  Benefits:

    Modular package declarations would be encouraged and errors due
    to demand-creation of packages would be easier to detect.

    The specification of COMPILE-FILE will be simplified.

    There will be a clear statement of the requirements for program
    conformance, as relating to usage of packages.

  Aesthetics:

    The fact that IN-PACKAGE is currently ambiguous about intent (whether
    the package should exist already or not) is clearly not aesthetic.
    Removing it can't be any worse.

    The fact that the currently stated requirements for handling of
    the package functions by the compiler are not implementable is
    clearly not aesthetic.
!
Proposal (IN-PACKAGE-FUNCTIONALITY:SELECT-ONLY):

  Eliminate the ability of IN-PACKAGE to create a package on demand.
  Eliminate the :NICKNAMES and :USE arguments to IN-PACKAGE, since they
  are no longer needed.

  The results of calling IN-PACKAGE if the package does not already
  exist are implementation dependent; implementations "should signal"
  an error, or otherwise provide the user with a way to recover from
  the situation. 

  Examples:

    #1: (IN-PACKAGE 'NO-SUCH-PACKAGE) 	;would signal an error

    #2: (DEFPACKAGE FOO ...options...)	;defines/creates a package
        (IN-PACKAGE 'FOO)		;selects an existing package

  Rationale:

    This could allow improved error checking and modularity, with only
    minimal loss of functionality. 

  Current Practice:

    Probably no one implements this behavior since it's in direct
    contradiction of both the definitions and numerous examples in CLtL.

  Cost to Implementors:

    As written, no change to implementations is required, but many will
    want to make IN-PACKAGE signal an error.  This change would be
    straightforward to implement.  The cost may not be trivial in all
    cases, but should not be very large.

  Cost to Users:

    In most cases, minor syntactic changes to some files would be
    necessary.

    In some cases, no changes would be necessary since files may
    already be doing IN-PACKAGE in situations where the author is
    hoping he's made sure the real package declaration is already
    loaded.

  Cost of Non-Adoption:

    Reduced error checking.
    Less modular code.

  Benefits:

    Errors due to demand-creation of a package by IN-PACKAGE without
    appropriate uses of the :USE or :NICKNAMES or without appropriate
    calls to EXPORT, etc. afterward would be easier to detect.

    Modular package declarations would be encouraged.

  Aesthetics:

    The fact that IN-PACKAGE is currently ambiguous about intent (whether
    the package should exist already or not) is clearly not aesthetic.
    Some people feel this change would be an aesthetic improvement.
    Others feel that an incompatible change to IN-PACKAGE would merely
    be confusing.

!
Discussion:

  The dual use of IN-PACKAGE has not been helpful and is confusing.

  Some people may find proposal NEW-MACRO more palatable if it merely
  deprecated IN-PACKAGE, instead of removing it entirely.

  Loosemore and Moon support proposal IN-PACKAGE-FUNCTIONALITY:NEW-MACRO.

  Pitman says:
    I support NEW-MACRO, though would really prefer you change "remove" to
    "deprecate".  Making this an incompatible change is gratuitous.

∂15-Mar-89  0924	CL-Characters-mailer 	BASE-CHARACTER    
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 15 Mar 89  09:24:27 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 557489; Wed 15-Mar-89 12:22:00 EST
Date: Wed, 15 Mar 89 12:22 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: BASE-CHARACTER
To: CL-Characters@SAIL.STANFORD.EDU
cc: X3J13@SAIL.STANFORD.EDU
In-Reply-To: <890315-060924-3563@Xerox>
Message-ID: <19890315172201.1.MOON@EUPHRATES.SCRC.Symbolics.COM>

After thinking it over, I agree with Larry Masinter's comments
in the referenced message and the suggestion to define BASE-CHARACTER
as (UPGRADED-ARRAY-ELEMENT-TYPE 'STANDARD-CHAR).

∂15-Mar-89  0936	CL-Cleanup-mailer 	Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
Received: from Aquinas.Think.COM by SAIL.Stanford.EDU with TCP; 15 Mar 89  09:36:35 PST
Received: from OCCAM.THINK.COM by Aquinas.Think.COM via INTERNET with SMTP id 124413; 15 Mar 89 12:34:29 EST
Date: Wed, 15 Mar 89 12:34 EST
From: Barry Margolin <barmar@FAFNIR.THINK.COM>
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
To: cl-cleanup@sail.stanford.edu
cc: X3J13@sail.stanford.edu
In-Reply-To: <890315-051405-3472@Xerox>
Message-ID: <19890315173420.1.BARMAR@OCCAM.THINK.COM>

    Date: 15 Mar 89 05:13 PST
    From: masinter.pa@xerox.com

    Proposal (ADJUST-ARRAY-NOT-ADJUSTABLE:CLARIFY):

Hooray!  We finally got our collective acts together on this one!

                                                barmar

∂15-Mar-89  0948	X3J13-mailer 	Issue: GENSYM-NAME-STICKINESS (Version 1)
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 15 Mar 89  09:48:17 PST
Received: from fafnir.think.com by Think.COM; Wed, 15 Mar 89 12:44:45 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Wed, 15 Mar 89 12:46:05 EST
Received: by verdi.think.com; Wed, 15 Mar 89 12:42:51 EST
Date: Wed, 15 Mar 89 12:42:51 EST
From: Guy Steele <gls@Think.COM>
Message-Id: <8903151742.AA02653@verdi.think.com>
To: cl-cleanup@sail.stanford.edu
Cc: x3j13@sail.stanford.edu
In-Reply-To: masinter.pa@xerox.com's message of 14 Mar 89 14:56 PST <890314-145716-2049@Xerox>
Subject: Issue: GENSYM-NAME-STICKINESS (Version 1)

Does KMP intend that GENSYM not be sticky for an integer argument
as well?  That is, there is no way to reset the counter?
--Guy

∂15-Mar-89  1016	X3J13-mailer 	Issue: EXTRA-RETURN-VALUES (Version 2)   
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 15 Mar 89  10:16:01 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 557537; Wed 15-Mar-89 13:12:57 EST
Date: Wed, 15 Mar 89 13:12 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: EXTRA-RETURN-VALUES (Version 2)
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu
In-Reply-To: <8902242235.AA14585@decwrl.dec.com>
Message-ID: <19890315181252.6.MOON@EUPHRATES.SCRC.Symbolics.COM>

This one took longer than the others to answer because it is
a more difficult issue.

    Date: 24 Feb 89 17:35
    From: chapman%aitg.DEC@decwrl.dec.com

    Problem: Is it OK to return extra values from Common Lisp functions?
 
    Proposal: EXTRA-RETURN-VALUES:NO
    Unless it is explicitly allowed in the standard,
    if a standard function
    returns a different number of return values from the number
    specified by the standard, the results are unspecified.

I see a couple of problems with this.  First, it is bootless to
prohibit extra return values without also forbidding returning
fewer values than specified.  For example, when SUBTYPEP returns
NIL NIL, both NILs must actually be returned, not defaulted.

Second, I don't understand how "the results are unspecified" can be
correct here.  First of all, that term doesn't appear in the error
terminology, and I don't know whether you meant "the return values are
unspecified" or "the consequences are unspecified".  But I don't see
how you could mean either of those, since in fact what happens when
a certain number of values is returned is fully specified by the
language, and there is neither ambiguity nor implementation freedom.

If we look at the Rationale:

    The reason is that
    additional arguments are visible to otherwise portable programs. "For
    instance, (multiple-value-call #'cons (floor x y)) looks portable, but it
    will try to pass the wrong number of arguments to CONS if FLOOR returns an
    extra value."                        

I think what you must have actually meant to propose is: Functions
specified in the standard must return exactly the number of values
specified in the standard, no more and no fewer.  You could phrase this
as a requirement on implementations or as something that a conforming
program is permitted to assume, I don't much care which.

I found 21 functions in the LISP package in Symbolics Genera 7.4 that
return multiple values.  Is this the correct number?  Just as it was
useful to know that there are exactly 775 symbols in the LISP package
(in CLtL Common Lisp), it would be a useful check to publish the number
of functions that are supposed to return more than one value, and also
the number that are supposed to return no values.

I found two functions that return a different number of values than
CLtL specifies.  GETHASH returns a third value, the key it found,
to go with the value it found (this might not be EQL to the argument
when the test is EQUAL or EQUALP).  READ-LINE returns two additional
values, the delimiter character and the input-editor argument given
to the delimiter character.  The first of these is a useful feature
that Common Lisp ought to have, the second is a necessary extension
for our environment that is not obviously useful in other environments.

After making and thinking about that assessment, my feeling is that I
would vote for this proposal if it was reworded in a way that I could
understand (which might or might not be what I suggested above) and if a
few specific functions (list to be supplied later) were specified to
allow additional values.  I think this list would include all of the I/O
functions and would not include any of the arithmetic functions.  I
haven't yet consulted with anyone else at Symbolics on this opinion,
though.

∂15-Mar-89  1018	X3J13-mailer 	BASE-CHARACTER  
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 15 Mar 89  10:17:14 PST
Received: from fafnir.think.com by Think.COM; Wed, 15 Mar 89 13:13:21 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Wed, 15 Mar 89 13:14:40 EST
Received: by verdi.think.com; Wed, 15 Mar 89 13:11:29 EST
Date: Wed, 15 Mar 89 13:11:29 EST
From: Guy Steele <gls@Think.COM>
Message-Id: <8903151811.AA02727@verdi.think.com>
To: CL-Characters@sail.stanford.edu
Cc: X3J13@sail.stanford.edu
Subject: BASE-CHARACTER

Larry's suggestion about defining BASE-CHARACTER to be simply
(UPGRADED-ARRAY-ELEMENT-TYPE 'STANDARD-CHAR) has a great deal
of charm, and I don't see anything wrong about it.
So I support it.
--Guy

∂15-Mar-89  1227	X3J13-mailer 	Re: Issue ERROR TERMINOLOGY, dpANS C
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 15 Mar 89  12:27:28 PST
Received: from snail.Sun.COM (snail.Corp.Sun.COM) by Sun.COM (4.1/SMI-4.0)
	id AA14532; Wed, 15 Mar 89 12:27:45 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.0)
	id AA13443; Wed, 15 Mar 89 12:23:50 PST
Received: by clam.sun.com (4.0/SMI-4.0)
	id AA28038; Wed, 15 Mar 89 12:27:22 PST
Date: Wed, 15 Mar 89 12:27:22 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8903152027.AA28038@clam.sun.com>
To: jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK
Subject: Re: Issue ERROR TERMINOLOGY, dpANS C
Cc: x3j13@sail.stanford.edu

Discussion continued on cl-editorial.

∂15-Mar-89  1446	X3J13-mailer 	Issue ERROR TERMINOLOGY   
To:   x3j13@SAIL.Stanford.EDU    
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>


Is it the case that ``fatal'' is well-defined? If so, ``harmless'' is
simply something that is not fatal. According to my mathematics
education, that renders the term well-defined.

``Indeed, there is no way to invoke GC in Common Lisp and with a few
exceptions such as messages, GC must have NO side effects.''

Unsolicited messages can happen, and there is a proposal on the
cl-editorial table to render them harmless. If GC can have no side
effects, then why not state that and not wonder about unsolicited
messages? If we did that, then any Common Lisp that does print a
progress note is *out* of conformance. 

Also, as I've said several times, rehashing, termination of processes,
progress messages, flushing IO buffers, closing streams, and a list of
possibly hundreds of things are side effects of GC that should be
guaranteed harmless (that is, not fatal).

``> Some things are not immediately harmful but may cause
> trouble later on.

Yes, lots of things are that way.''

The definition of fatal puts no time constraints on the fatality. Therefore,
neither does its negation.

``> By ``unpredictable but harmless'', I think we are in effect saying
> ``not completely unpredictable''.  That is, we promise something but
> don't quite say what it is.  For example, Lisp will presumably not
> break off and start playing chess.  But maybe it's harmless to start
> playing chess.''

The beauty of a specification is knowing what not to say in order to
allow rational interpreters the freedom to interpret rationality now
and in the unpredictable future. There is considerable genius in the
fine line that Steele tread in CLtL on this. Does anyone rationally
think that a Common Lisp would be taken seriously that while GCing
broke out in a game of chess or an Irish gig? I refuse to seriously
debate with anyone who would use that as an example of something that
we must utter one word in the specification to prevent.

``As far as I can see, the only reasonable option is to specify
some range of possible consequences.  The constraints, whatever
they may be, make it possible to reason about what the program
will do.''

The reason this won't easily work is that it presumes that we are able
to accurately predict future implementation techniques and even to
fully comprehend current ones. I'm sure that KMP or I could supply an
endless stream of new and bizarre cases that have to be explicitly
dealt with. (I single out KMP because he has uncanny creativity.)

But, I'll change the debate a little. I've claimed that ``harmless''
is well-defined if and only if ``fatal'' is well-defined or at least
defined well enough. So, to convince me that ``harmless'' should be
pitched, you must convince me that ``fatal'' must be pitched.

			-rpg-

∂15-Mar-89  1451	CL-Compiler-mailer 	Issue SAFE-CODE, version 1    
To:   cl-compiler@SAIL.Stanford.EDU, x3j13@SAIL.Stanford.EDU   
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>


According to my understanding of the dictionary definitions,
``unsafe'' means primarily ``the opposite or reversal of `safe' '' and
secondarily ``not safe.'' This coincides with Moon's reading.
Therefore, I propose we use the term ``nonsafe'' which clearly means
``not safe.''  This, coupled with the already very explicit definition
of ``unsafe,'' which explains that unsafe code might actually be safe,
should take care of his objection.


			-rpg-

∂15-Mar-89  1506	CL-Editorial-mailer 	Re: Issue ERROR TERMINOLOGY, dpANS C   
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 15 Mar 89  15:06:13 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK   via Janet with NIFTP
           id aa11469; 15 Mar 89 19:24 GMT
Date: Wed, 15 Mar 89 19:21:20 GMT
Message-Id: <2039.8903151921@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Issue ERROR TERMINOLOGY, dpANS C
To: Cris Perdue <cperdue@sun.com>, chapman <@decwrl.dec.com:chapman@aitg.dec>
Cc: kempf <@sun.com:kempf@clam>, peck <@sun.com:peck@clam>, 
    sgadol <@sun.com:sgadol@clam>, x3j13@sail.stanford.edu, 
    cl-editorial@sail.stanford.edu, rpg <@sail.stanford.edu:rpg@lucid.com>

Perhaps this discussion should be in cl-editorial...

> From: Cris Perdue <cperdue@com.sun>
> The error terminology is OK, except for "consequences
> are unspecified".  That concept is broken, though it
> has serious defenders.  For example, Dick Gabriel says,
> 
>   "If we were to drop this term, then every time we are
>   ``explicitly vague'' a valid possibility is that a fatal
>   error can occur.  How is it any better to say that what happens
>   when some operation happens is ``explicitly vague''."

Perhaps the problem is that "harmless" is not very well defined.
Maybe we can convince ourselves that ``the consequences of the garbage
collector when invoked'' are harmless, but how many other examples can
we find?  Some things are not immediately harmful but may cause
trouble later on.  For example, are the consequences of using EQ to
compare numbers harmless?  Suppose we know that a fatal error will not
immediately occur.  Is that enough to make it harmless (in this case)?
[I know this is most likely to be a case where the ``return values are
unspecified'', but it was the best I could do on short notice, and we
can ask whether these consequences would be ``harmless'' even if they
wouldn't be described as such in the standard.]

By ``unpredictable but harmless'', I think we are in effect saying
``not completely unpredictable''.  That is, we promise something but
don't quite say what it is.  For example, Lisp will presumably not
break off and start playing chess.  But maybe it's harmless to start
playing chess.

> A typical area of "explicit vagueness" is the destructive operations
> on lists.  The explicit vagueness here is quite limited.  For
> some operations any top level cell of certain lists may or may
> not be modified.  Similar statements apply to other operations.
> The consequences are far from being unspecified but harmless.
> They are CONSTRAINED but meaningful.

This is an interesting example.  First, there's the question ``the
consequences of what?''  The consequences of applying the destructive
operation?  The consequences of doing anything that depends on whether
or not cells were modified?  We really have to see how these phrases
are used in the actual description of a function.

Maybe what we want is this:
The result is a list with certain (specified) properties.
The side effects on cells in the argument list are unspecified.

In addition, there might be a general warning that the consequences of
depending on unspecified side effects are undefined.

In an earlier message, Cris Perdue said:

   Let's pick a few actual examples where the language definition is
   proposed to say "consequences are unspecified".  (Go ahead, I
   challenge you.)  I think we will find that the description will
   have to be more specific than that.  It can make sense to say that
   "effect X may or may not occur".  It can make sense to say that
   "data structure Y may be modified arbitrarily".  If we can define a
   set of effects that we consider harmless, and change "unpredictable
   but harmless" to just "harmless", or some such, that could also
   make sense, but not the current language.

I am not quite convinced by this argument.  We have to be careful not
to make too much undefined.  If we consider some operation, some
things may be specified, some things left open, and so on.  The
description may have to be ``more specific'' in that we shouldn't
describe the whole thing as ``unspecified'' when we can instead say
something more precise; but that doesn't show that some parts of the
description cannot reasonably use ``unspecified'' or ``undefined''.

Besides, this argument applies just as well to ``undefined'' as it
does to ``unspecified'' -- there would be the same need to be more
specific.  So again I suspect it is the ``harmless'' that is really at
fault.

Anyway, the draft C standard makes a somewhat different distinction
between ``unspecified'' and ``undefined''.  In particular, correct
programs may have unspecified behavior; those with undefined behavior
are incorrect, or at least nonportable:

  Unspecified behavior -- behavior, for a correct program construct
  and correct data, for which the Standard imposes no requirements.

  Undefined behavior -- behavior, upon use of a nonportable or
  erroneous program construct, of erroneous data, or of
  indeterminately-values objects, for which the Standard imposes no
  requirements.  Permissible undefined behavior ranges from ignoring
  the situation completely with unpredictable results, to behaving
  during translation or program execution in a documented manner
  characteristic of the environment (with or without the issuance of a
  diagnostic message), to terminating translation or execution (with
  the issuance of a diagnostic message).

There is also a category of ``implementation-defined behavior".

An example: in a function call if the argument types or the number of
arguments are wrong [this is said more precisely in the standard]
``the behavior is undefined''.  However:  ``The order of evaluation of
the function designator, the arguments, and subexpressions within the
arguments is unspecified, but there is a sequence point before the
actual call."

The Rationale (a separate document) says:

  The terms unspecified behavior, undefined behavior, and
  implementation-defined behavior are used to categorize the result of
  writing programs whose properties the Standard does not, or cannot,
  completely describe.  The goal of adopting this categorization is to
  allow a certain variety among implementations which permits quality
  of implementation to be an active force in the marketplace, as well
  as to allow certain popular extensions, without removing the cachet
  of conformance to the standard.  An appendix to the standard, A.6,
  catalogs those behaviors that fall into one of these three
  categories.

  Unspecified behavior gives the implementor some latitude in
  translating programs.  This latitude does not extend so far as
  failing to translate the program.

  Undefined behavior gives the implementor license not to catch
  certain program errors that are difficult to diagnose.  It also
  identifies areas of possible conforming language extension: the
  implementor may augment the language by providing a definition of
  the officially undefined behavior.

From all this I conclude that we probably do need both unspecified and
undefined.  However, it is unclear exactly what distinction they
should express.

[The C standard also distinguishes between strictly conforming [more or
less: portable] programs and conforming programs.]

-- Jeff

∂15-Mar-89  1553	X3J13-mailer 	Re: Issue: EXTRA-RETURN-VALUES 
Received: from ti.com by SAIL.Stanford.EDU with TCP; 15 Mar 89  15:52:37 PST
Received: by ti.com id AA13974; Wed, 15 Mar 89 15:08:09 CST
Received: from Kelvin by tilde id AA23610; Tue, 14 Mar 89 11:36:42 CST
Message-Id: <2814888931-7906489@Kelvin>
Sender: GRAY@Kelvin.csc.ti.com
Date: Tue, 14 Mar 89  11:35:31 CST
From: David N Gray <Gray@DSG.csc.ti.com>
To: chapman%aitg.DEC@decwrl.dec.com
Cc: x3j13@sail.stanford.edu
Subject: Re: Issue: EXTRA-RETURN-VALUES
In-Reply-To: Msg of 24 Feb 89 17:35 from chapman%aitg.DEC@decwrl.dec.com

> Proposal: EXTRA-RETURN-VALUES:NO
> Unless it is explicitly allowed in the standard,
> if a standard function
> returns a different number of return values from the number
> specified by the standard, the results are unspecified.
> 
>  
> Rationale:
> 
> The reason is that
> additional arguments are visible to otherwise portable programs. "For
> instance, (multiple-value-call #'cons (floor x y)) looks portable, but it
> will try to pass the wrong number of arguments to CONS if FLOOR returns an
> extra value."                        

This may be a bit of over-kill.  I suggest making this restriction only
for functions which the standard specifies as returning multiple values.
For functions that the standard says return one value, there would be no
reason for a portable program to go out of its way to accept more than
one value from them, so additional values shouldn't hurt.

Also, "the results are unspecified" doesn't seem to be the right
terminology to use here since this is intended to be a restriction on
the implementation.  How about:

 Unless it is explicitly allowed in the standard, functions which are
 specified to return other than one value may not be extended by
 implementations to return more values than specified.

∂15-Mar-89  1603	X3J13-mailer 	Feb. 21 letter ballot
Received: from ti.com by SAIL.Stanford.EDU with TCP; 15 Mar 89  16:00:39 PST
Received: by ti.com id AA14034; Wed, 15 Mar 89 15:09:30 CST
Received: from home by tilde id AA26164; Tue, 14 Mar 89 13:07:13 CST
Received: by home id AA15845; Tue, 14 Mar 89 13:07:05 CST
Date: Tue, 14 Mar 89 13:07:05 CST
From: David Bartley <bartley@home.csc.ti.com>
Message-Id: <8903141907.AA15845@home>
To: x3j13@sail.stanford.edu
Subject: Feb. 21 letter ballot
Reply-To: Bartley@ti-csl.csc.ti.com

This is TI's vote on the Feb. 21 letter ballot:

________________________________________________________________________
Issue or section name          |   Version      |  Y   |   I   |   A   |
------------------------------------------------------------------------
CUT-OFF-DATES                  |      4         |  Y   |       |       |
------------------------------------------------------------------------
ERROR-TERMINOLOGY              |      5         |      |   I   |       |
------------------------------------------------------------------------
FONTS                          |      2         |  Y   |       |       |
------------------------------------------------------------------------
TOC                            |      1         |  Y   |       |       |
------------------------------------------------------------------------
Section 1.8                    |     5.8        |      |   I   |       |
------------------------------------------------------------------------
Section 2.3                    |     5.8        |      |   I   |       |
------------------------------------------------------------------------
Section 2.4                    |     5.8        |  Y   |       |       |
------------------------------------------------------------------------
Section 2.5                    |     5.8        |  Y   |       |       |
------------------------------------------------------------------------
Section 6.1                    |     5.8        |  Y   |       |       |
------------------------------------------------------------------------

Concerning ERROR-TERMINOLOGY: We understand that this section is
undergoing a significant rewrite.

(By the way, in the definition of CONFORMING CODE, shouldn't there be
a third point saying that conforming code does not depend on the
results of any "undefined" or "unspecified" situations?)

Concerning Section 1.8: This writeup is too terse to be very meaningful
---it looks like a preliminary outline instead of a final draft.

Concerning Section 2.3: Page 2-13 of the draft concerns David Gray
because it does not include any of the classes from page 1-17 of
88-002R.  Why did we go through all that hassle of redefining the
FUNCTION type if it is not going to be defined here as a class?
Shouldn't all of the classes on page 1-17 be included?

--db--

∂15-Mar-89  1722	X3J13-mailer 	Bartley's Comments   
To:   x3j13@SAIL.Stanford.EDU    
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>


David writes:

``(By the way, in the definition of CONFORMING CODE, shouldn't there be
a third point saying that conforming code does not depend on the
results of any "undefined" or "unspecified" situations?)''

The descriptions of unspecified and undefined already state exactly this.
Do you think it should be repeated in the definition of conforming code?

			-rpg-

∂15-Mar-89  1756	X3J13-mailer 	Issue: BREAK-ON-WARNINGS-OBSOLETE (Version 1) 
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 15 Mar 89  17:56:25 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 15 MAR 89 17:17:14 PST
Date: 15 Mar 89 17:16 PST
From: masinter.pa@Xerox.COM
Subject: Issue: BREAK-ON-WARNINGS-OBSOLETE (Version 1)
To: x3J13@sail.stanford.edu
line-fold: NO
reply-to: CL-CLEANUP@Sail.stanford.edu
Message-ID: <890315-171714-1269@Xerox>

!
Issue:        BREAK-ON-WARNINGS-OBSOLETE
Forum:	      Cleanup
References:   *BREAK-ON-WARNINGS* (CLtL p432, CL Condition System p40)
	      *BREAK-ON-SIGNALS* (CL Condition System p25)
Category:     CLARIFICATION/CHANGE
Edit history: 07-Mar-89, Version 1 by Pitman

Problem Description:

  With the advent of *BREAK-ON-SIGNALS*, *BREAK-ON-WARNINGS* is
  redundant and unnecessary.

Proposal (BREAK-ON-WARNINGS-OBSOLETE:DEPRECATE):

  Deprecate *BREAK-ON-WARNINGS*.

Test Case:

  N/A

Rationale:

  This will lead to simplification of the description of WARN.

  Not only are the two variables overkill, but they have an effect
  in an identifiably but uselessly distinct place.

Current Practice:

  Since deprecation is not removal, presumably everyone who conforms
  is compatible.

Cost to Implementors:

  Since the feature is deprecated rather than flushed: none.

Cost to Users:

  Since the feature is deprecated rather than flushed: none.

  Users should get used to writing (SETQ *BREAK-ON-SIGNALS* 'WARNING)
  rather than (SETQ *BREAK-ON-WARNINGS* T).

Cost of Non-Adoption:

  The definition of WARN will be gratuitously cluttered.

Benefits:

  Cost of non-adoption is avoided.

Aesthetics:

  Slight improvement.

Discussion:

  Pitman thinks this is a good idea, but doesn't think a lot of time
  should be wasted discussing the issue if there is strong opposition.

∂15-Mar-89  1853	X3J13-mailer 	Re: Issue: EXTRA-RETURN-VALUES 
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 15 Mar 89  18:53:34 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA03073; Wed, 15 Mar 89 17:50:24 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA04907; Wed, 15 Mar 89 17:50:16 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903160050.AA04907@defun.utah.edu>
Date: Wed, 15 Mar 89 17:50:14 MST
Subject: Re: Issue: EXTRA-RETURN-VALUES
To: David N Gray <Gray@DSG.csc.ti.com>
Cc: chapman%aitg.DEC@decwrl.dec.com, x3j13@sail.stanford.edu
In-Reply-To: David N Gray <Gray@DSG.csc.ti.com>, Tue, 14 Mar 89  11:35:31 CST

> Date: Tue, 14 Mar 89  11:35:31 CST
> From: David N Gray <Gray@DSG.csc.ti.com>
> 
> This may be a bit of over-kill.  I suggest making this restriction only
> for functions which the standard specifies as returning multiple values.
> For functions that the standard says return one value, there would be no
> reason for a portable program to go out of its way to accept more than
> one value from them, so additional values shouldn't hurt.

I disagree.  I've been known to use an idiom like

    (multiple-value-call #'foo (fn1) (fn2))

where FN1 is a standard Common Lisp function which is supposed to return
one value, and FN2 is a function that returns multiple values.  If FN1
is allowed to return extra values, this won't work.

-Sandra
-------

∂15-Mar-89  1941	CL-Compiler-mailer 	issue COMPILE-ENVIRONMENT-CONSISTENCY, version 4  
Received: from moon.src.honeywell.com (ALTURA.HONEYWELL.COM) by SAIL.Stanford.EDU with TCP; 15 Mar 89  19:40:55 PST
Return-Path: <alarson@src.honeywell.com>
Received: from pavo.SRC.Honeywell.COM by moon.src.honeywell.com (5.59/smail2.6.3/06-17-88);
	Wed, 15 Mar 89 21:39:48 CST id AA08835 for cl-compiler@sail.stanford.edu
Posted-Date: Wed, 15 Mar 89 21:38:06 CST
Received: by pavo.src.honeywell.com (3.2/SMI-3.2)
	id AA16529; Wed, 15 Mar 89 21:38:06 CST
Date: Wed, 15 Mar 89 21:38:06 CST
From: alarson@src.honeywell.com (Aaron Larson)
Message-Id: <8903160338.AA16529@pavo.src.honeywell.com>
To: cl-compiler@sail.stanford.edu
Cc: x3j13@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Mon, 13 Mar 89 15:50:07 -0700 <8903132250.AA02499@defun.utah.edu>
Subject: issue COMPILE-ENVIRONMENT-CONSISTENCY, version 4

If we permit the compiler to signal warnings for functions where the
compile-time environment signature is different from the function call
being compiled, why do we prohibit it for generic functions?

From COMPILE-ENVIRONMENT-CONSISTENCY:

    (3) The compiler *must not* make any additional assumptions about
    consistency between the compiletime and runtime environments.  In 
    particular:

	(a) The compiler may not ...  It is, however,
	    permissible for the compiler to emit warning messages when
	    compiling calls to functions that are defined in the compiletime
	    environment, but where the wrong number or type of arguments
	    are supplied.

But then in CLOS-MACRO-COMPILATION:

  
  DEFMETHOD:
  
  * The method is not callable at compile-time.  If there is a generic
    function with the same name at compile-time, compiling a DEFMETHOD
    will not add the method to that generic function.  The compiler may
    perform tests for lambda-list congruence only between the DEFGENERICs
    and DEFMETHODs for a given generic function name that appear within
    the file being compiled, and not against a generic function of the 
    same name which exists in the compile-time environment.
  

∂16-Mar-89  0601	X3J13-mailer 	Re: issue COMPILER-VERBOSITY, version 6  
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  06:01:53 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 89 05:48:37 PST
Date: 16 Mar 89 05:47 PST
From: masinter.pa@Xerox.COM
Subject: Re: issue COMPILER-VERBOSITY, version 6
To: cl-compiler@sail.stanford.edu
cc: x3J13@sail.stanford.edu
Message-ID: <890316-054837-3596@Xerox>

The current practice of this proposal says that one implementation has a
:VERBOSE that is used for what this proposal calls :PRINT, gives no current
examples of :VERBOSE, etc.  I'm suspicious of a proposal to add something
that is significantly more complex than what any current implementation
already has.

COMPILE-FILE is significantly more part of the "environment" than LOAD is,
and I think that the less we specify its behavior, the better off we are.
While there are useful programmatic portable invocations of LOAD where
controlling the output behavior portably is important, the case for
portable control of output behavior of COMPILE-FILE is much less strong.
What about environments that support incremental compilation? Where
compilation is handled by a background process? Wouldn't this be
unnecessary junk for them to add?

If we have some doubts about whether some of these 'puppies' are really
useful, shouldn't we leave them behind? Not require them? 

Larry

∂16-Mar-89  0632	X3J13-mailer 	Re: issue COMPILED-FUNCTION-REQUIREMENTS, version 4
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  06:32:40 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 89 06:23:30 PST
Date: 16 Mar 89 06:22 PST
From: masinter.pa@Xerox.COM
Subject: Re: issue COMPILED-FUNCTION-REQUIREMENTS, version 4
In-reply-to: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>'s message
 of Tue, 14 Mar 89 20:27 EST
To: cl-compiler@sail.stanford.edu
cc: X3J13@sail.stanford.edu
Message-ID: <890316-062330-3633@Xerox>

I think the previous sentiment was more strongly toward removing
COMPILED-FUNCTION rather than tightening its definition. However, in the
heat of the FUNCTION-TYPE discussion, this seemed to be a controversial
backward incompatibility (why not just leave it in, but leave it
unspecified?) 

I've extracted some quotes about COMPILED-FUNCTION from the CL-CLEANUP
discussion on FUNCTION-TYPE. Of course, these are taken out of context... 

Return-Path: <@SAIL.STANFORD.EDU:Moon@STONY-BROOK.SCRC.Symbolics.COM>
Received: from SAIL.STANFORD.EDU by Xerox.COM ; 02 MAR 87 21:29:49 PST
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 2 Mar
87  21:27:23 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by
STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 82Date: Tue, 3
Mar 87 00:26 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: Tue, 3 Mar 87 00:26 EST

It might be wise to add LEXICAL-CLOSURE and INTERPRETED-FUNCTION data
types, to go along with the COMPILED-FUNCTION type that already exists.
These three would be disjoint subtypes of FUNCTION, but not necessarily
an exhaustive partition.  There might be other ways to slice the space
of types, since it's not so clear what a function not inside a closure
is good for.  Alternatively we could flush COMPILED-FUNCTION and say
that the subtypes of FUNCTION are all implementation-dependent.  But I
think having COMPILED-FUNCTION without the others is weird.
- - - - - - - - -
Return-Path: <@SAIL.STANFORD.EDU:FAHLMAN@C.CS.CMU.EDU>
Received: from SAIL.STANFORD.EDU by Xerox.COM ; 08 MAR 87 21:56:23 PST
Received: from C.CS.CMU.EDU by SAIL.STANFORD.EDU with TCP; 8 Mar 87
21:53:10 PST
Received: ID <FAHLMAN@C.CS.CMU.EDU>; Mon 9 Mar 87 00:53:51-EST
Date: Mon, 9 Mar 87 00:53 EST
From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>

Probably we should explicitly name COMPILED-FUNCTION and
INTERPRETED-FUNCTION as subtypes of FUNCTION, and make TYPEP work for
them.  
- - - - - - - - -
Return-Path: <RPG@SAIL.STANFORD.EDU>
Received: from SAIL.STANFORD.EDU by Xerox.COM ; 08 MAR 87 23:54:05 PST
Date: 08 Mar 87 23:51 PST
From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>

Possibly these should not be required to be pairwise disjoint (?).

I think we shouldn't presume that all implementations implement 
functions as closures. I can imagine an implementation with
COMPILED-FUNCTIONs, INTERPRETED-FUNCTIONs, COMPILED-CLOSUREs,
and INTERPRETED-CLOSUREs.
- - - - - - - - -
Return-Path: <@SAIL.STANFORD.EDU:FAHLMAN@C.CS.CMU.EDU>
Received: from SAIL.STANFORD.EDU by Xerox.COM ; 09 MAR 87 08:07:46 PST
Received: from C.CS.CMU.EDU by SAIL.STANFORD.EDU with TCP; 9 Mar 87
08:01:49 PST
Received: ID <FAHLMAN@C.CS.CMU.EDU>; Mon 9 Mar 87 10:57:49-EST
Date: Mon, 9 Mar 87 10:57 EST
From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>

Well, these make sense only in systems that do support both compiled and
interpreted code.  In compiler-only or interpreter-only systems, I guess
the best move would be to say that every function is a member of both of
these subtypes: it is both a fast function and a slow function.

Now you're the one who is letting the user see internal stuff that is
none of his concern.  All of these functions are closures, in that they
no longer have any free variables waiting to be closed.  In some cases,
there may have been none in the first place, and implementors may want
to use some efficient internal form in such cases, but is there any
reason the user needs to know that?  A confusing concept that does him
no good (I think).
- - - - - - - - -
Return-Path: <@SAIL.STANFORD.EDU:Moon@STONY-BROOK.SCRC.Symbolics.COM>
Received: from SAIL.STANFORD.EDU by Xerox.COM ; 10 MAR 87 07:54:56 PST
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 10 Mar
87  07:48:09 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by
STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 89098; Tue
10-Mar-87 01:57:50 EST
Date: Tue, 10 Mar 87 01:57 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>

... I vacillate between
saying that all of the subtypes of FUNCTION are implementation-dependent
and shouldn't be standardized (thus COMPILED-FUNCTION should be
removed), and saying that programs might want to know this information,
so all the plausible subtypes should have standard names, even if they
aren't distinct in some implementations.  The only thing I feel strongly
and consistently about is that COMPILED-FUNCTION should not be the only
standardized subtype of FUNCTION; it should either acquire some siblings
or go away.
- - - - - - - - -
Return-Path: <@SAIL.STANFORD.EDU:KMP@STONY-BROOK.SCRC.Symbolics.COM>
Received: from SAIL.STANFORD.EDU by Xerox.COM ; 13 MAY 87 00:13:57 PDT
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 13 May
87  00:12:36 PDT
Received: from TSUKUBA.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM
via CHAOS with CHAOS-MAIL id 138655; Wed 13-May-87 03:10:55 EDT
Date: Wed, 13 May 87 03:10 EDT
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>

 * It seems to me that we might as well go ahead and create types
   INTERPRETED-FUNCTION and COMPILED-FUNCTION since the combination of
   the FUNCTION type and the COMPILED-FUNCTION-P predicate already
implements
   this distinction. Perhaps eventually COMPILED-FUNCTION-P could be
flushed.
- - - - - - - - -
Return-Path: <@SAIL.STANFORD.EDU:FAHLMAN@C.CS.CMU.EDU>
Received: from SAIL.STANFORD.EDU by Xerox.COM ; 17 MAY 87 19:32:45 PDT
Received: from C.CS.CMU.EDU by SAIL.STANFORD.EDU with TCP; 17 May 87
19:31:22 PDT
Received: ID <FAHLMAN@C.CS.CMU.EDU>; Sun 17 May 87 22:30:44-EDT
Date: Sun, 17 May 87 22:30 EDT
Message-ID: <FAHLMAN.12303231779.BABYL@C.CS.CMU.EDU>
Sender: FAHLMAN@C.CS.CMU.EDU

One possibility is not to define any of these and to eliminate
COMPILED-FUNCTION-P.  That's what I proposed in version 3.  The other
possibility is to define COMPILED-FUNCTION and INTERPRETED-FUNCTION as
subtypes of FUNCTION, but then we have to spell out what happens in
implementations that have only one internal representation or that have
more than two -- raw interpreted, transformed, and fully compiled, for
example.  Then there's the question of whether closures are, or can be,
a separate subtype.  In some sense, all true functions are closures,
since to get one you close a lambda expression in some lexical
environment.  However, we might want to reserve the word "closure" for
functions that actually capture some part of the lexical context outside
the function itself, and to create CLOSURE types based on this idea.

In my view, we are better off avoiding this whole thing and leaving it
to the individual implementations.
- - - - - - - - -
Date: 29 May 87 21:18 PDT
Subject: Issue: FUNCTION-TYPE (version 4)
From: Masinter.pa

Proposal FUNCTION-TYPE:REDEFINE

...
No sub-types of FUNCTION are defined in Common Lisp, but implementations
are free to define subtypes of FUNCTION.  Examples might be
COMPILED-FUNCTION, INTERPRETED-FUNCTION, and so on. Note that this
is a change from the current Common Lisp definition which explicitly
defines a COMPILED-FUNCTION type. This proposal removes the predicate
COMPILED-FUNCTION-P from the standard language.
- - - - - - - - -
Return-Path: <@SAIL.STANFORD.EDU:Moon@STONY-BROOK.SCRC.Symbolics.COM>
Received: from SAIL.STANFORD.EDU by Xerox.COM ; 01 JUN 87 21:23:10 PDT
Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 1 Jun
87  21:21:48 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by
STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 161267; Tue
2-Jun-87 00:11:30 EDT
Date: Tue, 2 Jun 87 00:11 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>

    This proposal removes the predicate
    COMPILED-FUNCTION-P from the standard language.

If it also removes the COMPILED-FUNCTION type-specifier, say so here.
- - - - - - - - -
Return-Path: <@SAIL.STANFORD.EDU:Masinter.pa@Xerox.COM>
Received: from SAIL.STANFORD.EDU by Xerox.COM ; 13 JUL 87 12:58:35 PDT
Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 13 Jul 87  12:54:07
PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 13 JUL 87 12:54:07 PDT
Date: 13 Jul 87 12:53 PDT
From: Masinter.pa

... My notes [from X3J13 meeting] include ...  that we be more consistent
about justifying removing COMPILED-FUNCTION-P (i.e., why bother?) ...
- - - - - - - - -
Date: 23 Oct 87 11:51 PDT
From: Masinter.pa
Subject: Issue: FUNCTION-TYPE (Version 6)

here is a revised version... I left COMPILED-FUNCTION and
COMPILED-FUNCTION-P as subtypes of FUNCTION.
...
Proposal FUNCTION-TYPE:STRICT-REDEFINITION
...
The COMPILED-FUNCTION subtype of FUNCTION is defined; implementations are
free to define other subtypes of FUNCTION, e.g., INTERPRETED-FUNCTION.  
- - - - - - - - -
(wording preserved through several iterations)
- - - - - - - - -
Return-Path: <CL-Cleanup-mailer@SAIL.Stanford.EDU>
Redistributed: xerox-cl-cleanup↑.pa
Received: from SAIL.Stanford.EDU by Xerox.COM ; 16 FEB 88 09:41:39 PST
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 16 Feb 88
09:39:23 PST
Received: by cs.utah.edu (5.54/utah-2.0-cs)
	id AA23751; Tue, 16 Feb 88 10:39:08 MST
Received: by orion.utah.edu (5.54/utah-1.0-slave)
	id AA25191; Tue, 16 Feb 88 10:39:04 MST
From: sandra%orion@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8802161739.AA25191@orion.utah.edu>
Date: Tue, 16 Feb 88 10:39:02 MST

Also, I have a question about 1b, where it states that COMPILED-FUNCTION
is a subtype of FUNCTION.  Does this imply that it must be a *proper*
subtype?  For example, in the Lisp I've been working on sporadically for
my Atari, the interpreted version of (FUNCTION (LAMBDA ...)) returns a
compiled function object (it's a closure which will apply the lambda
expression to the function arguments).  Likewise I can conceive of
implementations which compile everything and don't have an "interpreter"
at all.  I think this needs to be clarified.
- - - - - - - - -
Return-Path: <CL-Cleanup-mailer@SAIL.Stanford.EDU>
Redistributed: xerox-cl-cleanup↑.pa
Received: from SAIL.Stanford.EDU by Xerox.COM ; 19 FEB 88 14:37:22 PST
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 19 Feb 88  14:34:11
PST
Received: from Cabernet.ms by ArpaGateway.ms ; 19 FEB 88 14:17:33 PST
Date: 19 Feb 88 14:17 PST
From: Masinter.pa
I intended not to require that it not be a "proper" subtype in the sense
that
there may be no data items that are FUNCTIONP but not COMPILED-FUNCTIONP.

This can be clarified. 
- - - - - - - - -
Return-Path: <edsel!jonl@labrea.Stanford.EDU>
Received: from labrea.Stanford.EDU by Xerox.COM ; 24 FEB 88 10:14:38 PST
Received: by labrea.Stanford.EDU; Wed, 24 Feb 88 09:35:20 PST
Received: from bhopal.lucid.com by edsel id AA21578g; Wed, 24 Feb 88
10:03:43 PST
Received: by bhopal id AA26979g; Wed, 24 Feb 88 10:09:26 PST
Date: Wed, 24 Feb 88 10:09:26 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>

Lucid Common Lisp distinguishes "compiled" closures which exist for the
purpose of supporting entry into the interpreter from functions which are
truly compiled.  It only takes a bit in a header word.  If an
implementation
really doesn't support an interpreter, then having every function be
COMPILED-FUNCTIONP  doesn't sound like much of a loss.  

But most implementations in fact do support an interpreter -- which 
typically runs code at anywhere from 30 to 600 times slower than when
compiled.  Thus it seems reasonable to require COMPILED-FUNCTIONP in
those implementations to be false on, say,
	(eval '#'(lambda (x) (list x)))
no matter what underlying technique is used to support interpreter
closures.
- - - - - - - - -
Date:  4 Sep 88 13:39 PDT
From: Masinter.pa
Subject: Issue: FUNCTION-TYPE (version 12)
line-fold: NO

This is the final version of the FUNCTION-TYPE issue, as passed at the June
88 X3J13 meeting; that is, it incorporates the amendments that were adopted
before the issue was adopted.

...
    1b. Define that the type COMPILED-FUNCTION is a subtype of FUNCTION.
        Implementations are free to define other subtypes of FUNCTION.

∂16-Mar-89  0713	X3J13-mailer 	Issue: TIME-ZONE-NON-INTEGER, v.1   
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  07:13:51 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 89 07:07:49 PST
Date: 16 Mar 89 07:07 PST
From: masinter.pa@Xerox.COM
To: x3J13@sail.stanford.edu
Subject: Issue: TIME-ZONE-NON-INTEGER, v.1
line-fold: NO
Message-ID: <890316-070749-3717@Xerox>

!
Issue:        TIME-ZONE-NON-INTEGER
References:   Section 25.4.1 (Time Functions) (p. 443-444)
Category:     CLARIFICATION
Edit history: 1-MAR-89, Version 1 by Chapman


Problem Description:

CLtL states that the time zone part of Decoded Time is an integer. However,
it is possible to have a non-integer time-zone.

Proposal (TIME-ZONE-NON-INTEGER:ALLOW)

Specify that the time zone part of Decoded Time is a rational number
(either an integer or a ratio).

Rationale:

For CL to accommodate all possible time designations, it is necessary
to allow time zone to be non-integer.
Some places in the world are on half-hour or quarter-hour times.

Current Practice:

VAX LISP allows time zone to be non-integer.

Adoption Cost:

Shouldn't be too big a change.

Benefits:

See Rationale.

Conversion Cost:

See Adoption Cost.

Aesthetics:

None.

Discussion:

∂16-Mar-89  0720	X3J13-mailer 	Issue: LOAD-TRUENAME (Version 1)    
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  07:20:34 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 89 07:13:53 PST
Date: 16 Mar 89 07:13 PST
From: masinter.pa@Xerox.COM
Subject: Issue: LOAD-TRUENAME (Version 1)
To: x3J13@SAIL.Stanford.EDU
Message-ID: <890316-071353-3747@Xerox>


!
Issue:        LOAD-TRUENAME
Forum:	      Cleanup
References:   LOAD (p426), PROVIDE (p188), REQUIRE (p188),
	      Issue REQUIRE-PATHNAME-DEFAULTS
Category:     ADDITION
Edit history: 13-Mar-89, Version 1 by Pitman

Problem Description:

 It is difficult to construct sets of software modules which work
 together as a unit and which port between different implementations.

 REQUIRE and PROVIDE were intended to provide this level of support
 but have `failed' to be portable in practice.

 Typical user configurations involve a `system definition' file which
 loads the modules of a `system' (collection of software modules).

 Among the specific problems which arise are:

  - File system types may vary. Different file syntax must be used for
    each site.

  - Even with the same Lisp implementation and host file system type,
    the directory in which a software system resides may differ from
    delivery site to delivery site.

  - Multiple `copies' of the same system may reside in different
    directories on the same machine.

Proposal (LOAD-TRUENAME:NEW-PATHNAME-VARIABLES):

 Introduce new variables:

   *LOAD-TRUENAME*					[Variable]

   This special variable is initially NIL, but is bound by LOAD to
   hold the truename of the pathname of the file being loaded.

   *COMPILE-FILE-TRUENAME*				[Variable]

   This special variable is initially NIL, but is bound by 
   COMPILE-FILE to hold the truename of the pathname of the file
   being compiled.
   
Example:

 ------ File SETUP ------
 (IN-PACKAGE 'MY-STUFF)
 (DEFMACRO COMPILE-TRUENAME () `',*COMPILE-FILE-TRUENAME*)
 (DEFVAR *SOURCE-FILE* (COMPILE-TRUENAME) "Just for debugging.")
 (DEFVAR *LOADED-FILE* *LOAD-TRUENAME*)
 (DEFUN LOAD-MY-SYSTEM ()
   (DOLIST (MODULE-NAME '("FOO" "BAR" "BAZ"))
     (LOAD (MERGE-PATHNAMES MODULE-NAME *LOAD-TRUENAME*))))
 ------------------------

 (LOAD "SETUP")
 (LOAD-MY-SYSTEM)

Rationale:

 This satisfies the most common instances of the frequently reported
 problem in the Problem Description.

Current Practice:

 Wide variation.

 In some implementations, calling LOAD binds or sets 
 *DEFAULT-PATHNAME-DEFAULTS* so that pathnames named in a file being
 LOADed will default to being `nearby.'

 Some implementations provide special variables that are similar or
 identical to one or both of those proposed.

 Some implementations have a way to represent the pathname for the
 current working directory, and make the default pathname default
 to that, so that loading without specifying a default again tends to
 get `nearby' files.

 None of these techniques is portable, unfortunately, because there
 is no agreement.

Cost to Implementors:

 Very small.

Cost to Users:

 None. This change is upward compatible.

Cost of Non-Adoption:

 Continued difficulty for anyone trying to put a system of modules
 in a form where they can be conveniently delivered using portable code.

Benefits:

 The cost of non-adoption is avoided.

Aesthetics:

 Negligible.

Discussion:

 Touretzky raised the issue most recently on Common-Lisp. A number
 of people immediately jumped on the bandwagon, indicating it was
 important to them, too.

 Pitman made three suggestions in response, of which the above is
 the first. The others included:
  2. Variables *LOAD-TRUENAMES* and *COMPILE-FILE-TRUENAMES* which hold
     lists of the truenames of all files being loaded or compiled,
     respectively, during the dynamic invocation of LOAD and COMPILE-FILE.
 
  3. Variable *LOAD-OR-COMPILE-FILE-TRUENAMES* which holds a list like
    ((LOAD truename) (COMPILE-FILE truename) ...)
    during the dynamic invocation of LOAD and COMPILE-FILE.
 
 Touretzky responded:
 ``I like KMP's proposals.  I like the second one best: have separate
   variables for files being loaded and files being compiled, and use
   them to maintain a stack so we can see the nesting of loads within
   files.''

 Pitman ultimately chose to present the first rather than the second
 because it seemed simpler, easier to explain, and more likely to
 pass at this late date.


!
Additional Comments:


"I favor LOAD-TRUENAME:NEW-PATHNAME-VARIABLES.  I think this
proposal would be greatly improved by adding two more variables,
*LOAD-PATHNAME* and *COMPILE-FILE-PATHNAME*, whose values are
the pathname opened by LOAD or COMPILE-FILE, rather than the
truename.  The need for these is more obvious if you think
about systems where the pathname cannot be easily reconstructed
from the truename.  This includes file systems with symbolic
links and some pathname systems with logical pathnames."


"I favor this.  I would even favor either of the other two ideas even at
this `late date'.  The behavior of each of the proposals is simple, its
easy to see what it will and won't do, and it satisfies a real demand.

I should note that I have never wanted the incremented functionally
offered by the `stack' proposals, but I could still vote for them."

∂16-Mar-89  0708	CL-Compiler-mailer 	Re: Issue SAFE-CODE, version 1     
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  07:08:22 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 89 07:03:17 PST
Date: 16 Mar 89 07:02 PST
From: masinter.pa@Xerox.COM
Subject: Re: Issue SAFE-CODE, version 1    
In-reply-to: Dick Gabriel <RPG@SAIL.Stanford.EDU>'s message of 15 Mar 89
 14:51 PST
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>
cc: cl-compiler@SAIL.Stanford.EDU, x3j13@SAIL.Stanford.EDU
Message-ID: <890316-070317-3708@Xerox>

I'm guessing that Moon's objections are more serious than yours.

Frankly, as long as we're playing definitions, I think the problem lies
with 

"Define that, formally, the term ``safe code'' is code refers to any
  code in which the OPTIMIZE quality for SAFETY has a value of 3."

I don't think this is a good definition. It is probably good to define that
"any code in which the OPTIMIZE quality for SAFETY has a value 3" is "safe
code", but there is other code that is "safe" too. 

It seems pretty awkward to say that:

(locally (declare (optimize (safety 0))) (list 1 2 3))

is "unsafe" or "nonsafe" or "potentially non-safe". We could use the words
that way, but it is pretty confusing. 

Counter-proposal: say "declared safe" or "not declared safe", since the
issue is not the (English) safety of the code but the declarations in
effect?




∂16-Mar-89  0719	X3J13-mailer 	Re: issue LOAD-TIME-EVAL, version 11
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 16 Mar 89  07:19:03 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA21484; Thu, 16 Mar 89 08:16:34 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA05509; Thu, 16 Mar 89 08:16:32 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903161516.AA05509@defun.utah.edu>
Date: Thu, 16 Mar 89 08:16:30 MST
Subject: Re: issue LOAD-TIME-EVAL, version 11
To: masinter.pa@Xerox.COM
Cc: x3j13@sail.stanford.edu
In-Reply-To: masinter.pa@Xerox.COM, 16 Mar 89 06:45 PST

> Date: 16 Mar 89 06:45 PST
> From: masinter.pa@Xerox.COM
> 
> Um, I looked for and didn't find a justification for why what was passed at
> the last meeting was inadequate. I'm puzzled as to why there are now two
> proposals when there was one before, what the differences are between them,
> etc.

What happened is that we got some e-mail on this issue after the
meeting, describing in more detail some objections to the wording of
the proposal that had been discussed very briefly at the meeting.
This person thought that the original wording was too vague and that
we would have trouble being more explicit about the semantics it was
intended to specify, and suggested some new wording for slightly
different semantics.  I think it is the consensus of the compiler
committee that the new language is an improvement.

The changed section of the proposal is clearly marked in the writeup
that was distributed.  It has to do with under what circumstances it
is permissible to cache LOAD-TIME-VALUE expressions.

-Sandra
-------

∂16-Mar-89  0831	X3J13-mailer 	Issue DESCRIBE-UNDERSPECIFIED, v.1  
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  08:31:39 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 08:20:29 PST
Date: 16 Mar 89 08:19 PST
From: masinter.pa@Xerox.COM
Subject: Issue DESCRIBE-UNDERSPECIFIED, v.1
To: x3j13@SAIL.STANFORD.EDU
line-fold: NO
Message-ID: <890316-082029-3881@Xerox>


!
Forum:		Cleanup
Issue:		DESCRIBE-UNDERSPECIFIED
References:	CLtL p441-2
		88-002R, DESCRIBE function
Category:	CHANGE, ADDITION
Edit history:	Version 1, 10-Mar-89, Kim A. Barrett

Problem description:

 The CLOS Specification (X3J13 Document 88-002R) changes the definition of the
 function DESCRIBE, making it a generic function.  However, it does not specify
 any of the protocol needed to make user-defined methods interact properly to
 produce some of the effects mentioned in CLtL.  For example, CLtL says that
 sometimes the method for describing an object will involve describing
 something that it finds inside the object, and that such recursive
 descriptions are indented appropriately.  How do user-written methods achieve
 this indentation?  Must they arrange for the indentation explicitly, or is
 there some automatic mechanism that handles it?

 The new specification does not easily lend itself to certain kinds of features
 which some implementations have included in their versions of DESCRIBE, such
 as analogues to the printer's depth limits (*PRINT-DEPTH*) and circular
 structure detection during recursion (*PRINT-CIRCLE*).

 In addition, DESCRIBE does not take a stream argument, instead always doing
 output to *STANDARD-OUTPUT*.  This means that a program which wants to use
 DESCRIBE to output some information to a particular stream must rebind
 *STANDARD-OUTPUT* around the call to DESCRIBE.  This is a nuisance, and is
 also potentially a bad idea in implementations which have interrupts and such.

Proposal DESCRIBE-UNDERSPECIFIED:DESCRIBE-OBJECT:

 Remove the section of 88-002R which specifies that DESCRIBE is a generic
 function.  Modify DESCRIBE to accept an optional second stream argument, which
 defaults to *STANDARD-OUTPUT*.  The value of this argument is the stream which
 output will be directed to.  Specify that DESCRIBE is implemented in terms of
 the generic function DESCRIBE-OBJECT, described below.

 DESCRIBE-OBJECT object stream				[Generic Function]

  The generic function DESCRIBE-OBJECT writes a description of an object to a
  stream.  The function DESCRIBE-OBJECT is called by the DESCRIBE function; it
  should not be called by the user.

  Each implementation is required to provide a method on the class
  STANDARD-OBJECT and methods on enough other classes so as to ensure that
  there is always an applicable method.  Implementations are free to add
  methods for other classes.  Users can write methods for DESCRIBE-OBJECT for
  their own classes if they do not wish to inherit an implementation-supplied
  method.

  ARGUMENTS:

   The first argument is any Lisp object.  The second argument is a stream; it
   cannot be T or NIL.

  VALUES:

   The values returned by DESCRIBE-OBJECT are unspecified.

  REMARKS:

   Methods on DESCRIBE-OBJECT may recursively call DESCRIBE.  Indentation,
   depth limits, and circularity detection are all taken care of automatically,
   provided that each method handles exactly one level of structure and calls
   DESCRIBE recursively argument if there are more structural levels.

   If this rule is not obeyed, the results are undefined.

   In some implementations the stream argument passed to a DESCRIBE-OBJECT
   method is not the original stream, but is an intermediate stream that
   implements parts of DESCRIBE.  Methods should therefore not depend on the
   identity of this stream.

Rationale:

 This proposal was closely modeled on the CLOS description of PRINT-OBJECT,
 which was well thought out and provides a great deal of functionality and
 implementation freedom.  The same implementation techniques applicable to
 PRINT-OBJECT will be applicable to DESCRIBE-OBJECT.

 The reason for making the return values for DESCRIBE-OBJECT unspecified is to
 avoid forcing users to include explicit (VALUES) in all their methods.
 DESCRIBE will take care of that.

Current practice:

 Probably nobody does precisely what this proposal suggests.

Cost to Implementors:

 A fair amount of work may be required, since every method/subfunction of
 DESCRIBE in an implementation may need at least some fixing to be in line with
 this proposal.  On the other hand, that work may already be needed in order to
 conform to 88-002R, and this proposal may make the conversion easier by
 simplifying the translation of an existing implementation of DESCRIBE.

Cost to Users:

 Any users who are using an implementation which supports the current CLOS
 specification of DESCRIBE and have defined their own methods will have to
 change them.  CLOS is sufficiently recent that this probably isn't a big
 problem.

 Those users who have made use of implementation-specific hooks into DESCRIBE
 to define their own methods will likely have to change, but that was already
 the case.

 Users who are currently binding *STANDARD-OUTPUT* around calls to DESCRIBE may
 wish to change their code.

Cost of non-adoption:

 Portable DESCRIBE methods may be difficult to write because the protocol they
 must follow is insufficiently specified.

Benefits:

 The constraints on DESCRIBE methods are better specified, making it easier to
 write such methods properly.

Aesthetics:

 Minimal.

Discussion:

 An additional change which is not included in the present proposal would be to
 make the syntax of DESCRIBE and DESCRIBE-OBJECT be

  DESCRIBE object &optional stream &key
  DESCRIBE-OBJECT object stream &key

 allowing implementation-specific extensions to the arguments.  A possible
 standard keyword argument is :VERBOSE, which might be used to specify how much
 output to produce.

 It might be desirable to define some new describe control variables analogous
 to the printer control variables, ie. *DESCRIBE-LEVEL* and *DESCRIBE-CIRCLE*,
 and possibly *DESCRIBE-LENGTH*.
-------



     ----- End Forwarded Messages -----

∂16-Mar-89  0854	X3J13-mailer 	Issue: CLOS-CONDITIONS (Version 4)  
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  08:54:08 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 89 08:44:08 PST
Date: 16 Mar 89 08:43 PST
From: masinter.pa@Xerox.COM
Subject: Issue: CLOS-CONDITIONS (Version 4)
To: X3J13@SAIL.Stanford.EDU
line-fold: NO
Message-ID: <890316-084408-3922@Xerox>

There've been various comments on this version; most of the
relevant discussion centers on whether the metaclass of
condition classes should be specified. Exerpts from
the mail appear at the end.

!
Status: DRAFT
Issue:        CLOS-CONDITIONS
References:   Condition System (Revision 18)
Category:     ADDITION
Edit history: 26-Sep-88, Version 1 by Pitman
	      06-Oct-88, Version 2 by Pitman
	      09-Oct-88, Version 3 by Pitman
	      10-Mar-89, Version 4 by Pitman (remove unsupported options)

Problem Description:

  The description of the Common Lisp condition system presupposes
  only DEFSTRUCT and not DEFCLASS because it was written when
  CLOS had not been adopted. It is stylistically out of step with
  CLOS in a few places and places some restrictions which are not
  necessary if CLOS can be presupposed.

Proposal (CLOS-CONDITIONS:INTEGRATE):

  1. Define that condition types are CLOS classes.

  2. Define that condition objects are CLOS instances.

  3. Functions such as SIGNAL, which take arguments of class names, are
     permitted to take class objects. Such class objects must still be
     subclasses of CONDITION.

  4. Define that slots in condition objects are normal CLOS slots. Note
     that WITH-SLOTS can be used to provide more convenient access to the
     slots where slot accessors are undesirable.

  5. Incompatibly change the syntax of a slot in DEFINE-CONDITION
     to be compatible with a DEFCLASS slot specification.

     An implication of this change is that forms like
      (DEFINE-CONDITION FOO (BAR) ((A 1) (B 2)))
     would have to be written
      (DEFINE-CONDITION FOO (BAR)
	((A :INITARG :A :READER FOO-A :INITFORM 1)
	 (B :INITARG :B :READER FOO-B :INITFORM 2)))

  6. Permit multiple parent-types to be named in the list of parent types.
     Define that these parent types are treated the same as the superior
     class list in a CLOS DEFCLASS expression.

  7. Eliminate the :CONC-NAME option to DEFINE-CONDITION.

  8. Define that condition reporting is mediated through the PRINT-OBJECT
     method for the condition type (class) in question, with *PRINT-ESCAPE*
     always being NIL. Specifying (:REPORT fn) in the definition of a
     condition type C is equivalent to doing 
      (DEFMETHOD PRINT-OBJECT ((X c) STREAM)
	(IF *PRINT-ESCAPE* (CALL-NEXT-METHOD) (fn X STREAM)))

Rationale:

  These changes are consistent with the intent of the X3J13 endorsement
  of CLOS and the Common Lisp Condition System.

  Although items 5 and 7 are incompatible with the interim condition
  handling which we've been working with, the overall proposal significantly
  improves compatibility with CLOS.

  This compatibility will make the language seem less fragmented, and
  probably more learnable because there will be fewer paradigms to learn.

  Also, items 5 and 7 in particular are an improvement for reasons
  unrelated to CLOS if only because they get rid of the need for symbol
  concatenation, a process which has been seen to cause problems because
  of the transient nature of the binding of *PACKAGE*.

Examples:

  Slot specifiers...

    A slot specifier of X is still valid but is incompatibly
    changed to mean what CLOS has it mean; no :INITARG or 
    :READER would be supplied.
  
    A slot specifier of (X) is still valid but is incompatibly
    changed to mean what CLOS has it mean; no :INITARG or 
    :READER would be supplied.

    A slot specifier of (X V) would no longer be valid.
    
    In addition, other slot specifiers such as
     (X :INITARG :EX :TYPE FIXNUM)
    are permitted as in DEFCLASS.

 Conc names ...

   (DEFINE-CONDITION FOOBAR (FOO BAR) (X Y) (:CONC-NAME FUBAR))
   would be rewritten
   (DEFINE-CONDITION FOOBAR (FOO BAR)
     ((X :INITARG :X :READER FUBAR-X)
      (Y :INITARG :Y :READER FUBAR-Y)))

 Report methods ...

   (DEFINE-CONDITION OOPS (ERROR) ())
   (DEFMETHOD PRINT-OBJECT ((X OOPS) STREAM)
     (IF *PRINT-ESCAPE* 
	 (CALL-NEXT-METHOD)
	 (FORMAT STREAM "Oops! Something went wrong.")))
   (ERROR 'OOPS)
   >>Error: Oops! Something went wrong.


Current Practice:

  Some implementations supporting CLOS probably already do this,
  or something very similar.

Cost to Implementors:

  If you really have CLOS, this is very straightforward.

Cost to Users:

  Small, but tractable.

  The main potential problems are:

   - :CONC-NAME. There is nothing that keeps an implementation from
     continuing to support :CONC-NAME for a short while until old code
     has been upgraded.

   - The incompatible change to slot syntax. Again, it is possible to
     unambiguously recognize a 2-list as old-style syntax and an
     implementation can provide interim compatibility support during
     a transition period.

  Even if implementations did not provide the recommended compatibility
  support, users could trivially shadow DEFINE-CONDITION and provide the
  support themselves, expanding into the native DEFINE-CONDITION in the
  proper syntax.

  In any case, the total number of uses of DEFINE-CONDITION at this 
  point is probably quite small. Searching for them and repairing
  each by hand is probably not an expensive operation.

Cost of Non-Adoption:

  Conditions will seem harder to manipulate than other user-defined types.

  People will wonder if CLOS is really something we're committed to.

Benefits:

  A more regular, more learnable language.

Aesthetics:

  Improved.

Discussion:

  Gregor, Pierson, Moon, and Pitman support this proposal.

  People seem to disagree about the status that CLOS might occupy
  in the upcoming standard. In spite of a vote of support, they seem
  to think it might be optional in some way. Passing this proposal
  establishes a clear precedent for the full integration of CLOS into
  the emerging language.

  The sense of the cleanup committee was that it was acceptable for
  a vendor to identify a CLOS-free subset of Common Lisp, but that since
  the position of X3J13 seems to be that no resources should be devoted
  to work on subsets, it was inappropriate for us to work out the details
  of that subset ourselves.  Since nothing about this proposal would
  impede such a subset, we took that to be adequate basis for presenting
  this single proposal.

  Moon thinks we might want to add condition types for the errors
  CLOS might signal. Richard Mlynarik thinks we should add a generic
  function, REPORT-CONDITION, which is used for reporting conditions.
  Both of these issues should probably be pursued under separate cover.


!
"One comment is that you should explicitly mention bootstrapping
concerns under cost to implementors.  If you just leave it out,
someone may think it is a difficult problem. "

"This isn't any sort of clarification.  The actual clarification required
-- which has been requested several times, and not just by myself -- is
what the *METACLASS* of condition types is.

Condition types may be "CLOS classes" without being STANDARD-CLASSes
Condition objects may be "CLOS instances" without being STANDARD-OBJECTs.
Just what are "normal CLOS slots"?  As I see it, the "normalcy" or
otherwise of slots is determined by the metaclass.


My opinion for some time has been that condition types should not be
STANDARD-CLASSes but instead something like READ-ONLY-CLASS.
Conceptually, It Is An Error to modify the slots of condition objects,
which are supposed to be immutable descriptions of part of the state of
a computation.  Implementationally,
(setf (slot-value <condition-object> <slot-name>) <new-value>) should
signal an error.

(I also think that conditions in particular have a strong need for
something like :REQUIRED-INIT-KEYWORDS, but that's another story.)

Even if you decide to make condition classes' metaclass STANDARD-CLASS,
the point is that you need to state this, so that users may define
condition classes and mixins using DEFCLASS."

"I do not agree that it is a -necessary- thing to specify the Meta-Class
of conditions because all intended uses of conditions can be done
without this information.

I agree that it is a -possibly useful- thing to do, but there is a down
side to it -- it would unnecessarily tie the hands of people who want
implementation flexibility for one reason or another."

"... If we don't specify the metaclass, then users
won't know what other classes they can mix in when defining condition
classes.  It may seem weird, but I can imagine someone wanting to mix
in an arbitrary class into a condition class.

I think we should just say that the class CONDITION is an instance of
STANDARD-CLASS, and that by default DEFINE-CONDITION defines standard
classes.  Sure it might be nice to do the read only class thing but I
don't think this is a good time to design a special purpose metaclass
for this.  "



∂16-Mar-89  0928	CL-Compiler-mailer 	Issue SAFE-CODE, version 1         
To:   cl-compiler@SAIL.Stanford.EDU
CC:   x3j13@SAIL.Stanford.EDU  
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>


The point of these definitions is to lay out terminology that
enables programmers to know with certainty on what ground they stand
with respect to the specification. ``Safe code'' is a technical term
that means that the code was ``processed'' under this declaration.

This means intuitively that it is as safe (English word) as it can get.
But it also means that it is ``safe code'' in the CL jargon, and eveything
we say about safe code there is also true of it. 

The meaning of safe code (English phrase), as in ``as safe as it can
get,'' is spelled out in the specification as the sequence of statements
we make about the attributes of safe code. It might be that some or all of
those attributes apply to code processed under lower safety optimization
levels, but the programmer can be sure only when the highest safety level
is used.

I think Moon's problem is that the usual practice is to borrow English
words for these technical terms, and that works fine until the
negation of the term is needed. We want some word to mean ``not `safe' ''.
``Unsafe'' is an available English word that does not mean the
complement of ``safe'', it means the reverse of safe. Thus, the parallel
senses of the technical pair ``safe/unsafe'' are not the same as the
vernacular pair safe/unsafe.

Also, the definitions of the terms point out that what is defined as
``unsafe code'' might actually be exactly as safe (English) as ``safe code.''

			-rpg-

∂16-Mar-89  0958	X3J13-mailer 	Re: Issue: EXTRA-RETURN-VALUES 
Received: from Aquinas.Think.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  09:57:58 PST
Received: from OCCAM.THINK.COM by Aquinas.Think.COM via CHAOS with CHAOS-MAIL id 124433; Wed 15-Mar-89 19:37:26 EST
Date: Wed, 15 Mar 89 19:37 EST
From: Barry Margolin <barmar@FAFNIR.THINK.COM>
Subject: Re: Issue: EXTRA-RETURN-VALUES
To: David N Gray <Gray@dsg.csc.ti.com>
cc: chapman%aitg.DEC@decwrl.dec.com, x3j13@sail.stanford.edu
In-Reply-To: <2814888931-7906489@Kelvin>
Message-ID: <19890316003719.1.BARMAR@OCCAM.THINK.COM>

    Date: Tue, 14 Mar 89  11:35:31 CST
    From: David N Gray <Gray@dsg.csc.ti.com>

    > Proposal: EXTRA-RETURN-VALUES:NO
    > Unless it is explicitly allowed in the standard,
    > if a standard function
    > returns a different number of return values from the number
    > specified by the standard, the results are unspecified.
    > 
    >  
    > Rationale:
    > 
    > The reason is that
    > additional arguments are visible to otherwise portable programs. "For
    > instance, (multiple-value-call #'cons (floor x y)) looks portable, but it
    > will try to pass the wrong number of arguments to CONS if FLOOR returns an
    > extra value."                        

    This may be a bit of over-kill.  I suggest making this restriction only
    for functions which the standard specifies as returning multiple values.
    For functions that the standard says return one value, there would be no
    reason for a portable program to go out of its way to accept more than
    one value from them, so additional values shouldn't hurt.

But MULTIPLE-VALUE-CALL permits multiple arguments, some of which might
be calls to functions documented as returning only one valid, e.g.

	(multiple-value-call #'three-arg-function (cons x y) (floor x y))

MV-CALL is being used to get the multiple values of FLOOR passed as the
second and third argument to THREE-ARG-FUNCTION, but this will fail if
CONS returns the wrong number of values.

                                                barmar

∂16-Mar-89  0958	X3J13-mailer 	Issue: TIME-ZONE-NON-INTEGER, v.1   
Received: from Aquinas.Think.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  09:58:20 PST
Received: from OCCAM.THINK.COM by Aquinas.Think.COM via INTERNET with SMTP id 124441; 16 Mar 89 12:16:49 EST
Date: Thu, 16 Mar 89 12:16 EST
From: Barry Margolin <barmar@FAFNIR.THINK.COM>
Subject: Issue: TIME-ZONE-NON-INTEGER, v.1
To: masinter.pa@xerox.com
cc: x3J13@sail.stanford.edu
In-Reply-To: <890316-070749-3717@Xerox>
Message-ID: <19890316171639.5.BARMAR@OCCAM.THINK.COM>

    Date: 16 Mar 89 07:07 PST
    From: masinter.pa@xerox.com

    Proposal (TIME-ZONE-NON-INTEGER:ALLOW)

    Specify that the time zone part of Decoded Time is a rational number
    (either an integer or a ratio).

Just to show you, when I become a billionaire I'll form my own country
and give it an irrational time zone (e in the winter, sqrt(2) in the
summer).

Seriously, is there any particular reason not to allow any non-complex
number as a time zone?

                                                barmar

∂16-Mar-89  0957	X3J13-mailer 	Re: Issue ERROR TERMINOLOGY, dpANS C
Received: from Aquinas.Think.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  09:57:06 PST
Received: from OCCAM.THINK.COM by Aquinas.Think.COM via CHAOS with CHAOS-MAIL id 124431; Wed 15-Mar-89 19:28:46 EST
Date: Wed, 15 Mar 89 19:28 EST
From: Barry Margolin <barmar@FAFNIR.THINK.COM>
Subject: Re: Issue ERROR TERMINOLOGY, dpANS C
To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
cc: Cris Perdue <cperdue@sun.com>, chapman <@decwrl.dec.com:chapman@aitg.dec>,
    kempf <@sun.com:kempf@clam>, peck <@sun.com:peck@clam>, sgadol <@sun.com:sgadol@clam>,
    x3j13@sail.stanford.edu, cl-editorial@sail.stanford.edu, rpg <@sail.stanford.edu:rpg@lucid.com>
In-Reply-To: <2039.8903151921@subnode.aiai.ed.ac.uk>
Message-ID: <19890316002837.0.BARMAR@OCCAM.THINK.COM>

A while back I proposed (to the Editorial committee) a definition of
"harmless" that I still like: Equivalent to an arbitrary conforming
program.  The point of this definition is to say that the consequences
of the situation are undefined, but it can't do anything that a valid
program can't do (if we had a denotational semantics, or a virtual
machine specification as I believe the C standard does, we could
probably use that to specify this).  For instance, it won't result in
pointers to unallocated data being stored in the application's data, or
changing components of function objects.  Undefined consequences would
allow such things, and they can result in secondary effects such as
crashing the system or the process dumping core.  Note that my
definition includes signaling an error among the harmless consequences.

Yes, this definition allows such situations to result in playing chess,
and if the computer is controlling a bomb silo it could also result in
starting World War III.  I don't think a general definition of
"unspecified" can possibly disallow these things.  We might want to
rethink the applicability of the word "harmless" in this case.  I think
market forces are adequate to guarantee that the actual results in any
particular implementation will be reasonable, and we won't have
computers all over the country playing chess when you ask them to CONS.

By the way, I've decided that the "consequences of the garbage collector
are unspecified" example is totally bogus.  The garbage collector is
completely transparent to a Common Lisp program.  The usual
counterargument (which I used to give) is that GC usually changes the
output of the ROOM function, but so can CONS, MAKE-ARRAY, etc.; the
language doesn't even guarantee that (PROGN (ROOM) (ROOM)) will print
the same output twice (it probably won't if ROOM conses).  It can also
be argued that GC can be detected by noticing how long operations take,
but on time-sharing systems there are other reasons why an operation may
take a long time.  GC may reorder the elements in a hash table, but we
never guarantee that MAPHASH of a hash table will consistently process
the elements in the same order, and SETF of GETHASH may also rehash the
table.  I challenge someone to write a conforming Common Lisp program
GC-P that takes as an argument a function, applies the function, and
returns a boolean result indicating whether a GC occurred during the
function execution.

If we can't come up with another example of an unspecified situation,
perhaps we should just throw out the term and stop fighting about it.

                                                barmar

∂16-Mar-89  0958	CL-Compiler-mailer 	Re: issue COMPILED-FUNCTION-REQUIREMENTS, version 4    
Received: from Aquinas.Think.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  09:58:47 PST
Received: from OCCAM.THINK.COM by Aquinas.Think.COM via INTERNET with SMTP id 124445; 16 Mar 89 12:31:52 EST
Date: Thu, 16 Mar 89 12:31 EST
From: Barry Margolin <barmar@FAFNIR.THINK.COM>
Subject: Re: issue COMPILED-FUNCTION-REQUIREMENTS, version 4
To: masinter.pa@xerox.com
cc: cl-compiler@sail.stanford.edu, X3J13@sail.stanford.edu
In-Reply-To: <890316-062330-3633@Xerox>
Message-ID: <19890316173142.7.BARMAR@OCCAM.THINK.COM>

I'll just reiterate something I said at one of the meetings.  One
portable use I can think of for the COMPILED-FUNCTION type is as a
declaration to allow compiler optimization.  If a function knows (or
requires) that a parameter is a compiled function it can declare that
and the implementation may be able to optimize the FUNCALL better.

Another thing I just thought of is something like:

	(when (typep f '(and function (not compiled-function)))
	  (setq f (compile nil f)))

This doesn't actually work because COMPILE isn't required to accept
lexical closures (well, at least it doesn't accept them in Genera 7.2),
but they satisfy the type specifier, but it would be nice if there were
a standard set of primitives that would allow one to write something
that does what the above tries to do.

                                                barmar

∂16-Mar-89  1040	X3J13-mailer 	Re: Issue ERROR TERMINOLOGY    
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 16 Mar 89  10:40:10 PST
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK   via Janet with NIFTP
           id aa08149; 16 Mar 89 18:31 GMT
Date: Thu, 16 Mar 89 18:29:06 GMT
Message-Id: <2499.8903161829@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Issue ERROR TERMINOLOGY   
To: Dick Gabriel <RPG@sail.stanford.edu>, x3j13@sail.stanford.edu
In-Reply-To: Dick Gabriel's message of 15 Mar 89  1446 PST

> Is it the case that ``fatal'' is well-defined? If so, ``harmless'' is
> simply something that is not fatal. According to my mathematics
> education, that renders the term well-defined.

"Harmless" does not mean "not fatal".

"Undefined" means the standard imposes no constraints (and irrational
implementors can do whatever they want and still have a conforming
implementation).  But "unspecified" imposes some constraints.  I
didn't find "harmless" a sufficiently enlightening description of
these constraints.  If no one feels inclined to suggest something
better now, I am happy to wait and see how "unspecified" gets used in
the standard before deciding whether or not "harmless" works.


∂16-Mar-89  1044	X3J13-mailer 	Issue: CLOSED-STREAM-OPERATION (Version 7)    
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  10:44:15 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 09:51:25 PST
Date: 16 Mar 89 09:43 PST
From: masinter.pa@Xerox.COM
Subject: Issue: CLOSED-STREAM-OPERATION (Version 7) 
To: x3j13@sail.stanford.edu
line-fold: NO
Message-ID: <890316-095125-4330@Xerox>

Version 5 of issue CLOSED-STREAM-OPERATION was brought up at
the January 1989 meeting.

The proposal CLOSED-STREAM-FUNCTIONS:ALLOW-INQUIRY was amended at
that meeting; the amended version passed.

Version 5 said

 "If CLOSE is called on a stream which is open, it will return T.
    However, if CLOSE is called on a stream which is closed, it
    will succeed without error but the return value is not specified."

The amendment was to change the wording so that CLOSE would
return NIL if given a closed stream, viz:

 " If CLOSE is called on a stream which is open, it will return T.
    However, if CLOSE is called on a stream which is closed, it
    will succeed with out error but the return value will be NIL."

Kent Pitman has made an argument that the amendment
was ill-considered.

I find his argument convincing.

I think procedurally we can vote to reconsider &
revoke the amendment, i.e., revert to Version 5.


Excerpts from the discussion:


Return-Path: <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by Xerox.COM ; 06 FEB 89 10:12:19 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 534168; Mon 6-Feb-89 13:11:33 EST
Date: Mon, 6 Feb 89 13:11 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>

...

I think one ought not be able to depend
on the result in this case [of CLOSE of a closed stream] 
because implementations might reasonably differ
about whether the first CLOSE really closed the stream. As such,

 (LIST (CLOSE *TERMINAL-IO*) (CLOSE *TERMINAL-IO*))

might reasonably return (T T) or (T NIL), for example, depending on whether
the implementation represents the concept of `open-ness' for all streams.
The same is true for string streams.

The issue is even weirder for composite (eg, broadcast) streams where some
streams are initially open and others are not, since I think we have no 
clear theory of whether such a stream is opened or closed.

...
Return-Path: <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Received: from STONY-BROOK.SCRC.Symbolics.COM ([128.81.41.144]) by Xerox.COM ; 15 FEB 89 07:04:19 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 539477; Wed 15-Feb-89 10:03:58 EST
Date: Wed, 15 Feb 89 10:03 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>





What's weird about this whole thing is that CLOSE-CONSTRUCTED-STREAM
talks about the effect of most operations being `unspecified' after
CLOSE. 

Unless you intend it to be an implication of CLOSE-CONSTRUCTED-STREAM
that you actually carry a CLOSED-P bit around in every stream so you
can tell if the stream is open or not and return the right value from
CLOSE, then it's a bad idea to legislate that CLOSE returns a certain
value, because you can't really guarantee that value.

If you do intend me to carry around a CLOSED-P bit, why bother to
claim that the effect of I/O to the stream after it's closed is 
`unspecified.' My assumption before was that it was unspecified in
case I want to define it, but suddenly it sounds like I'm not really
allowed to extend it -- I'm just permitted to optimize out the error
checks for the sake of efficiency. If this is so, why not just put it
in the domain of `should signal' so that at least the users could get
some mileage out of it because my implementation pretty much has its
hands tied at this point.

We get calls all the time from users who claim we're in violation of
things that really CLtL leaves vague. This will be such a thing given
the way it's all worded.

Here I am implementing CLOSE. I -really- want to implement it correctly.
I am willing to do anything necessary to make it return the right value
as long as what I do is something that is backed up in writing.
Here you are designing CL -- creating the writing that will back me up.
If you cannot show me how to write CLOSE in a way so that I can simply
point to a sentence in the manual that explains off my behavior whenever
anyone complains so I can get them off the phone and get back to work,
then you owe me a sentence in the manual that says that I'm entitled to
do whatever I feel like and the user cannot depend on it.

False security is worse than no security at all.
∪End of message∪

∂16-Mar-89  1051	X3J13-mailer 	Re: Issue ERROR TERMINOLOGY, dpANS C     
Received: from multimax.encore.com by SAIL.Stanford.EDU with TCP; 16 Mar 89  10:51:31 PST
Received: from mist.encore.COM by multimax.encore.com with SMTP (5.61/25-eef)
	id AA06620; Thu, 16 Mar 89 13:49:18 -0500
Received: from localhost by mist. (4.0/SMI-4.0)
	id AA07280; Thu, 16 Mar 89 13:47:38 EST
Message-Id: <8903161847.AA07280@mist.>
To: Barry Margolin <barmar@FAFNIR.THINK.COM>
Cc: x3j13@sail.stanford.edu, cl-editorial@sail.stanford.edu
Subject: Re: Issue ERROR TERMINOLOGY, dpANS C 
In-Reply-To: Your message of Wed, 15 Mar 89 19:28:00 -0500.
             <19890316002837.0.BARMAR@OCCAM.THINK.COM> 
Date: Thu, 16 Mar 89 13:47:36 EST
From: Dan L. Pierson <pierson@mist.encore.com>

    Date: Wed, 15 Mar 89 19:28 EST
    From: Barry Margolin <barmar@FAFNIR.THINK.COM>
    
    A while back I proposed (to the Editorial committee) a definition of
    "harmless" that I still like: Equivalent to an arbitrary conforming
    program.  The point of this definition is to say that the consequences
    of the situation are undefined, but it can't do anything that a valid
    program can't do (if we had a denotational semantics, or a virtual
    machine specification as I believe the C standard does, we could
    probably use that to specify this).  For instance, it won't result in
    pointers to unallocated data being stored in the application's data, or
    changing components of function objects.  Undefined consequences would
    allow such things, and they can result in secondary effects such as
    crashing the system or the process dumping core.  Note that my
    definition includes signaling an error among the harmless consequences.
    
I like this idea.

∂16-Mar-89  1044	X3J13-mailer 	Issue: COERCE-INCOMPLETE (Version 3)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  10:44:26 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 09:59:01 PST
Date: 16 Mar 89 09:57 PST
From: masinter.pa@Xerox.COM
Subject: Issue: COERCE-INCOMPLETE (Version 3)
To: x3j13@sail.stanford.edu
line-fold: NO
Message-ID: <890316-095901-4371@Xerox>

There are some additional comments at the end.
!
Issue:		 COERCE-INCOMPLETE
Reference:	 COERCE (p50)
Category:	 ADDITION/CHANGE
Edit history:	 Version 1 of COERCE-INCOMPLETE, 26-Feb-88 by M. Ida
		 Version 1 of COERCE-FROM-TYPE,  20-Jun-88 by Pitman
		 Version 2 of COERCE-INCOMPLETE, 21-Nov-88 by Pitman
		  (consolidate previous two proposals)
		 Version 3 of COERCE-INCOMPLETE, 07-Mar-89 by Pitman
		  (eliminate unpopular proposal, two new options)

Problem Description:

  COERCE is difficult to extend because ambiguities arise about the
  source type of the coercion.

  For example, if the symbol STRING were permitted as a second argument
  to coerce, as in (COERCE NIL 'STRING), there would be two posssible
  return values: "" or "NIL". The choice would be arbitrary and would
  have to be specified by the documentation. No matter which was chosen,
  it would probably turn out to be a problem for some applications at
  some times.

  Another example is (COERCE (CHAR-CODE #\A) 'STRING). This might
  return the same as (FORMAT NIL "~D" (CHAR-CODE #\A)) -- "65" in
  most ASCII-based implementations -- or it might return "A". Again,
  the choice would be arbitrary.

  There is clear desire on the part of the user community to lift some of
  the existing restrictions on arguments to COERCE, but because of legitimate
  concerns about ambiguities, the Common Lisp designers have thus far
  refused to do so.

  Unfortunately, the failure of COERCE to handle these cases means it is
  very difficult to learn to use COERCE. And the fact that COERCE is not
  easily learned contributes to difficulty in learning Common Lisp because
  instead of a single coercion operator with general purpose semantics, a
  number of very special purpose coercion operators must be learned instead.

  Some middle ground needs to be found, which neither compromises the
  clear semantics and portable nature of COERCE nor complicates COERCE
  in a way that makes it unlearnable.

  Also, some people have expressed a desire for COERCE to be more 
  `symmetric.' Usually they seem to mean that they want it to be the case
  that if (COERCE x y) works, then (COERCE (COERCE x y) (TYPE-OF x)) 
  should also work. Although this is not an essential desire, it would
  certainly be nice to achieve.
 
Proposal (COERCE-INCOMPLETE:LIMITED-ARBITRARY-EXTENSION):

  Define COERCE to accept the following equivalences:

   1. (COERCE x 'STRING)    == (STRING x)
   2. (COERCE x 'PATHNAME)  == (PATHNAME x)
   3. (COERCE x 'RATIONAL)  == (RATIONAL x)

  Clarify that

   4. (COERCE x 'FLOAT)     == (FLOAT x)

  Rationale:

    Many users think of STRING, for example, as ``the way to coerce
    something to a string'' and are baffled why COERCE and STRING
    disagree on how to do this.

    Such users think that if there's a moral battle to be waged
    over how to coerce an object to a STRING, the battle has already
    been lost by defining the STRING function -- that whatever
    decision is made for STRING must also apply to COERCE for the
    sake of simplicity.
 
    Similar arguments can be made for PATHNAME, FLOAT, and RATIONAL.

Proposal (COERCE-INCOMPLETE:DEPRECATE):

  Deprecate COERCE.

  Rationale:

    COERCE is not functionally necessary -- no operation that it does
    cannot be done in some other way.  As such, it is basically just
    a matter of syntactic convenience, and perhaps isn't worth having
    around if it will be the subject of endless debate.  Deprecating
    it would allow us to declare this issue a `dead end' and focus our
    attention on matters of greater substance.

Current Practice:

  Presumably No one implements either of the proposals at this time,
  since none are compatible with CLtL.

Cost to Implementors:

  COERCE: Small to moderate.

  DEPRECATE: None.

Cost to Users:

  COERCE: This is an incompatible change. (COERCE 'NIL 'STRING) => ""
    but (STRING NIL) => "NIL".  How many applications are impacted by
    this change is not clear. It would be straightforward to shadow
    COERCE with an alternate definition that did the old thing in
    cases where people were worried. Once such cases have been 
    identified, rewriting 
     (COERCE X 'STRING)
    as
     (IF X (COERCE X 'STRING) "")
    will suffice in most cases.

  DEPRECATE: No immediate work would be needed, although many maintained
    applications would get upgraded in order to use the primitives that
    are `in vogue.'

Cost of Non-Adoption:

  People will continue to see and debate the issues alluded to in
  the Problem Description.

Benefits:

  The cost of Non-Adoption will be avoided.

Aesthetics:

  COERCE: Many people will probably see the idea of making
    COERCE consistent with STRING, PATHNAME, FLOAT, and
    RATIONAL as a clear improvement -- possibly outweighing
    the costs of both an incompatible change and a decision
    to arbitrarily favor one treatment over the other.

  DEPRECATE: Some may take the deprecation of COERCE as an
    aesthetic improvement because it eliminates the need to
    debate this issue further. Others may see the 
    ``de-centralization'' of coercion as a step backward.

Discussion:

  Pitman supports COERCE-INCOMPLETE:LIMITED-ARBITRARY-EXTENSION.
  Hopefully Moon and Masinter support it, too, since it's
  basically patterned after a bunch of mail they were sending
  back and forth.

  A proposal to extend COERCE to permit a ``view type'' argument
  was considered and rejected as too extreme to consider seriously
  in the timeframe available.

  Pierson suggests that COERCE ought to be a candidate for
  generic function status.

  Pitman thinks that making [two-argument] COERCE generic would
  be a -very- bad idea  but believes that his earlier proposal
  involving a third `view type' argument might be able to 
  accomodate such extension.

!
Additional comments:

"... The thing about
COERCE-INCOMPLETE:LIMITED-ARBITRARY-EXTENSION that strikes fear
into my heart is that it wipes out CLtL's simple statement that
any sequence type may be converted to any other sequence type,
and starts people asking questions like does
(coerce nil '(vector character)) => "" or "NIL"?

... I'm inclined to vote
no on both proposals and keep the (unsatisfactory) status quo."

"I believe that any change to the status quo is incomplete without
providing a coercion mechanism whose "viewpoint" is that of a sequence.
That is effectively what the current COERCE is, overloaded with those
types which do not conflict with SEQUENCE.

Because of the problem of differing viewpoints, I'm inclined to think
that COERCE should be shrunk down to only being a sequence coercion
function, and all other coercions should be handled by the appropriate
functions."

∂16-Mar-89  1045	X3J13-mailer 	DRAFT Issue: CONDITION-RESTARTS (Version 1)   
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  10:44:53 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 10:30:53 PST
Date: 16 Mar 89 10:24 PST
From: masinter.pa@Xerox.COM
Subject: DRAFT Issue: CONDITION-RESTARTS (Version 1)
To: x3j13@SAIL.Stanford.EDU
line-fold: NO
Message-ID: <890316-103053-4587@Xerox>

There will possibly be a new version of this issue available
at the meeting. Additional comments excerpted at the end...
!
Issue:        CONDITION-RESTARTS
Forum:	      Cleanup
References:   Common Lisp Condition System
Category:     CHANGE
Edit history: 18-Jan-89, Version 1 by Pitman

Problem Description:

  It was noted in the condition system document itself, and many people have
  complained privately, that a major weakness of the condition system is the
  inability to know whether a particular restart is associated with a 
  particular signalling action.

  The problem being addressed shows itself in situations involving recursive
  errors. The programmer wants to make sure that a restart obtained from
  FIND-RESTART or COMPUTE-RESTARTS is in fact present for the purpose of
  handling some particular error that he is actively focussed on, and not
  for some other (outer) error which he was not actively trying to handle.

Proposal (CONDITION-RESTARTS:PERMIT-ASSOCIATION):

  1. Define that it is an error for SIGNAL to be called on a condition
     more than once.

  2. Introduce a function COPY-CONDITION:

     COPY-CONDITION condition					[Function]

      Returns a copy of the given condition.
 
  3. Introduce a macro WITH-CONDITION-RESTARTS which can be used to
     dynamically bind the association between a condition and a set
     of restarts.
 
     WITH-CONDITION-RESTARTS (condition-form restarts-form) &BODY forms
								[Macro]

      Evaluates CONDITION-FORM and RESTARTS-FORM, the results of which
      should be a condition and a list of restarts, respectively. Then
      evaluates the body of forms in implicit-progn style, returning the
      last form. While in the dynamic context of the body, the function
      COMPUTE-RESTARTS will, when given an argument that was the result
      of evaluating the CONDITION-FORM, return the list of restarts that
      was the result of evaluating the RESTARTS-FORM.

      Only the innermost call to WITH-CONDITION-RESTARTS with a given
      condition is relevant. In this way, the set of restarts associated
      with a given condition can be dynamically extended or restricted.

      Usually this macro is not used explicitly in code, since 
      SIGNAL-WITH-RESTARTS and ERROR-WITH-RESTARTS handle most of the
      common cases in a way that is syntactically more concise.

  4. Extend COMPUTE-RESTARTS, FIND-RESTART, ABORT, CONTINUE, USE-VALUE,
     and STORE-VALUE to permit an optional condition object as an argument.

     When the extra argument is not supplied, these functions behave
     exactly as defined before. (Restarts are considered without
     prejudice to whether they have been associated with conditions.)

     When this argument is supplied, only restarts with the associated 
     with the given condition are considered. In all other respects, the
     behavior is the same.

     Passing a condition argument of NIL is treated the same as passing
     no condition argument.

  5. Add two new macros SIGNAL-WITH-RESTARTS and ERROR-WITH-RESTARTS:

     SIGNAL-WITH-RESTARTS condition &rest restart-clauses	[Macro]

      This does several things:
	1. It enters a context in which the indicated RESTART-CLAUSES
	   are available. They have the same form as the clauses in
	   a RESTART-CASE.
        2. It evaluates CONDITION expression. [This is done after the
	   restarts are instantiated because the restarts are probably
	   still useful in the debugger if an error occurs during the 
	   evaluation of the condition.] The result of the evaluation
	   must be a condition object.
	3. It associates the condition which resulted from the evaluation
	   with the restarts established in step 1, using the equivalent
	   of WITH-CONDITION-RESTARTS.
	4. It calls SIGNAL on the same condition.

     ERROR-WITH-RESTARTS  condition &rest restart-clauses	[Macro]

      Like SIGNAL-WITH-RESTARTS but uses ERROR rather than SIGNAL
      in step 4.

  6. Define that Common Lisp macros such as CHECK-TYPE, which are defined
     to signal and to make restarts available, use the equivalent of
     WITH-CONDITION-RESTARTS to associate the conditions they signal with
     the defined restarts, so that users can make reliable tests not only
     for the restarts being available, but also for them being available
     for the right reasons.

Rationale:

  1. The ability to recycle a condition object (including the ability to
     resignal a condition) means that the same condition object might be
     simultaneously active for two different purposes. In such a case,
     no test (not even EQ) would suffice to determine whether a particular
     restart belonged with a particular signalling action, since the 
     condition could not uniquely identify the signalling action. By saying
     that a given condition may only be signalled once, we guarantee that
     the condition can serve as a unique identifier for a signalling action.

  2. Since there may now be some code which has begun to rely on the ability
     to re-signal a condition, COPY-CONDITION will help to make this
     transition easier. Instead of 
      (SIGNAL already-signalled-condition)
     one can write:
      (SIGNAL (COPY-CONDITION already-signalled-condition))

  3. This is is the minimal level of support needed to set up an 
     association between restarts and conditions.

  4. This provides a natural interface for retrieving and using the
     information about the associations between conditions and restarts.

  5. This provides a natural interface for the most common case of
     wanting to signal a restart with some associated conditions.

Test Case:

  (HANDLER-BIND ((ERROR #'(LAMBDA (C) (SIGNAL C)))) (SIGNAL "Test"))
  was permissible, but this proposal makes it an error.

  (DEFUN TEST-CONDITION-STUFF (OFFER-EXTRA-RESTART 
			       USE-CONDITION-ARGUMENT
			       USE-FOUND-RESTART)
    (HANDLER-BIND ((CONDITION
		     #'(LAMBDA (C)
			 (LET ((R0 (FIND-RESTART 'USE-VALUE))
			       (R1 (IF USE-CONDITION-ARGUMENT
				       (FIND-RESTART 'USE-VALUE C)
				       (FIND-RESTART 'USE-VALUE))))
			   (IF (AND R1 USE-FOUND-RESTART)
			       (INVOKE-RESTART R1 (EQ R0 R1))
			       (USE-VALUE (EQ R0 R1)))))))
      (HANDLER-BIND ((CONDITION
		       #'(LAMBDA (C)
			   (USE-VALUE
			     (IF OFFER-EXTRA-RESTART
				 (WITH-RESTARTS
				     (SIGNAL (COPY-CONDITION C))
				   (USE-VALUE (X) (LIST 'EXTRA X)))
				 (SIGNAL (COPY-CONDITION C)))))))
	(SIGNAL-WITH-RESTARTS (MAKE-CONDITION 'SIMPLE-CONDITION
					      :FORMAT-STRING "Test")
	  (USE-VALUE (X) X)))))

  Previously, this was an error because it uses non-existent primitives, but
  if you assume that
    - COPY-CONDITION is implemented in the `obvious' way
    - SIGNAL-WITH-RESTARTS just uses WITH-RESTARTS and SIGNAL
    - FIND-RESTART ignores its last argument
  in the obvious naive ways, it is possible to compare the old and new behavior:

				        Current    Proposed
  (TEST-CONDITION-STUFF NIL NIL NIL) => T	   T
  (TEST-CONDITION-STUFF NIL NIL T)   => T	   T
  (TEST-CONDITION-STUFF NIL T   NIL) => T	   T
  (TEST-CONDITION-STUFF NIL T   T)   => T	   T
  (TEST-CONDITION-STUFF T   NIL NIL) => T	   (EXTRA T)
  (TEST-CONDITION-STUFF T   NIL T)   => T	   (EXTRA T)
  (TEST-CONDITION-STUFF T   T   NIL) => T          (EXTRA NIL)
  (TEST-CONDITION-STUFF T   T   T)   => T	   NIL

Current Practice:

  Presumably no implementation does this yet.

Cost to Implementors:

  Several small, relatively modular changes.

Cost to Users:

  Except for the change to the recyclability of restarts, this change is 
  upward compatible.

  Probably very few if any users currently take advantage of recycling
  restarts, so the cost to users of this change is very slight.
  
  Even in the case where recycling is used, a straightforward rewrite in
  terms of COPY-CONDITION is probably feasible.

Cost of Non-Adoption:

  Use of restarts would not be nearly as reliable.

Benefits:

  It would be possible to write code which was considerably more robust.

Aesthetics:

  Some people might consider this proposal to make things slightly better
  because it avoids some ambiguities. Others might consider it to make
  things slightly worse because it adds additional complexity.

Discussion:

  Pitman thinks a change of this sort is important.

!
"CONDITION-RESTARTS:PERMIT-ASSOCIATION looks fine to me.
    It would certainly clean things up in some code I'm working on.."

"I strongly favor this proposal; it removes the major objection that I
had to the CL condition system as it developed.

However, I don't favor the COPY-CONDITION function.  I don't think it's
necessary.  More importantly, you have not proposed any concrete specification
of what it does, and unless someone does, it cannot be included in the
language.  Fortunately, I think we can just drop it, as I doubt that any
portable program would use it in any significant way that could not just
as well be done with a tiny amount of code using other existing primitives.


[generally agreed]

" .. how (should) the condition/restart association
   might be implemented -- is some kind of alist structure held by a
   special variable what was intended, or ought the condition have a
   restarts slot? ... it's pretty obvious that the relation should be externally
   represented. It's important that the association not be done by a slot
   in the condition because if you carry around the condition object after
   you're done signalling, you don't want it to contain useless and/or
   misleading information about restarts that no longer exist."

"... syntax to SIGNAL-WITH-RESTARTS and 
       ERROR-WITH-RESTARTS should be:
	SIGNAL-WITH-RESTARTS signal-argument-list &rest restart-clauses
	ERROR-WITH-RESTARTS  signal-argument-list &rest restart-clauses
       so that you would write
	(SIGNAL-WITH-RESTARTS ('FOOD-COLOR-ERROR :FOOD 'LETTUCE :COLOR 'PINK)
	  ...restart clauses...)
       rather than
	(SIGNAL-WITH-RESTARTS (MAKE-CONDITION 'FOOD-COLOR-ERROR
				:FOOD 'LETTUCE :COLOR 'PINK)
	  ...restart clauses...)
       If you wanted to use MAKE-CONDITION, you would then write:
	(SIGNAL-WITH-RESTARTS ((MAKE-CONDITION 'FOOD-COLOR-ERROR
				 :FOOD 'LETTUCE :COLOR 'PINK))
	  ...restart clauses...)
       The advantage of what he proposes is that you could write
	(SIGNAL-WITH-RESTARTS ("Bad ~S color" 'FOOD)
	  ...restart clauses...)
       and a condition object would be created implicitly as with SIGNAL. A
       possible disadvantage is that
	(SIGNAL-WITH-RESTARTS (FOO BAR BAZ)
	  ...restart clauses...)
       might look to someone like the FOO in (FOO BAR BAZ) named a function
       rather than a variable. "

"... even better would be 

  (WITH-CONDITION-RESTARTS signal-form &rest restart-clauses)

where signal-form must be an invocation of SIGNAL, ERROR, WARN, or
perhaps a few others, or a macro that expands into such an invocation.
WITH-CONDITION-RESTARTS must signal an error at all levels of safety if
it does not recognize the signal-form.  This is "weird" because it uses
a form for something other than evaluation (but not unprecedented; this
is exactly what SETF does).  The advantage is that it just nests with an
existing syntax instead of inventing a new, awkward syntax.

Note that I stole the "good name" WITH-CONDITION-RESTARTS for this
commonly used syntax.  The less commonly used primitive that just sets
up the restarts without signalling doesn't need as good a name."


"... the syntax for WITH-CONDITION-RESTARTS should be 
	WITH-CONDITION-RESTARTS condition-form restarts-form &BODY forms
       rather than
	WITH-CONDITION-RESTARTS (condition-form restarts-form) &BODY forms
       which it is now. Does anyone else have an opinion?

This is probably a good idea.  I'd probably name this one
WITH-CONDITION-RESTARTS-INTERNAL.  But are we sure that this operation
needs to be named in the standard
"

∂16-Mar-89  1117	CL-Compiler-mailer 	issue COMPILE-ENVIRONMENT-CONSISTENCY, version 4  
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 16 Mar 89  11:16:55 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 558656; Thu 16-Mar-89 14:13:55 EST
Date: Thu, 16 Mar 89 14:13 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: issue COMPILE-ENVIRONMENT-CONSISTENCY, version 4
To: Aaron Larson <alarson@src.honeywell.com>
cc: cl-compiler@sail.stanford.edu, x3j13@sail.stanford.edu
In-Reply-To: <8903160338.AA16529@pavo.src.honeywell.com>
Message-ID: <19890316191343.7.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Wed, 15 Mar 89 21:38:06 CST
    From: alarson@src.honeywell.com (Aaron Larson)

    If we permit the compiler to signal warnings for functions where the
    compile-time environment signature is different from the function call
    being compiled, why do we prohibit it for generic functions?

I would say that what CLOS-MACRO-COMPILATION (which I have not reviewed yet)
is clearly incorrect.  Perhaps CLOS-MACRO-COMPILATION was trying only to rule
out signalling an error for a lack of lambda-list congruency between
compile-time and run-time, but went overboard and ruled out warnings
as well.  I think warnings in this circumstance can be desirable, but
errors are certainly wrong.

∂16-Mar-89  1146	X3J13-mailer 	Issue ERROR TERMINOLOGY, dpANS C    
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  11:44:03 PST
Received: from fafnir.think.com by Think.COM; Thu, 16 Mar 89 14:40:15 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Thu, 16 Mar 89 14:41:04 EST
Received: by verdi.think.com; Thu, 16 Mar 89 14:37:31 EST
Date: Thu, 16 Mar 89 14:37:31 EST
From: Guy Steele <gls@Think.COM>
Message-Id: <8903161937.AA05048@verdi.think.com>
To: barmar@Think.COM
Cc: jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK, cperdue@sun.com,
        @decwrl.dec.com:chapman@aitg.dec, @sun.com:kempf@clam,
        @sun.com:peck@clam, @sun.com:sgadol@clam, x3j13@sail.stanford.edu,
        cl-editorial@sail.stanford.edu, @sail.stanford.edu:rpg@lucid.com
In-Reply-To: Barry Margolin's message of Wed, 15 Mar 89 19:28 EST <19890316002837.0.BARMAR@OCCAM.THINK.COM>
Subject: Issue ERROR TERMINOLOGY, dpANS C

   Date: Wed, 15 Mar 89 19:28 EST
   From: Barry Margolin <barmar@Think.COM>

   A while back I proposed (to the Editorial committee) a definition of
   "harmless" that I still like: Equivalent to an arbitrary conforming
   program ...
   Yes, this definition allows such situations to result in playing chess,
   and if the computer is controlling a bomb silo it could also result in
   starting World War III.  I don't think a general definition of
   "unspecified" can possibly disallow these things.  We might want to
   rethink the applicability of the word "harmless" in this case....

How about renaming "harmless" to be "arbitrary"?
--Guy

∂16-Mar-89  1205	X3J13-mailer 	Issue: TIME-ZONE-NON-INTEGER, v.1   
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  12:03:57 PST
Received: from fafnir.think.com by Think.COM; Thu, 16 Mar 89 14:41:11 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Thu, 16 Mar 89 14:42:22 EST
Received: by verdi.think.com; Thu, 16 Mar 89 14:39:11 EST
Date: Thu, 16 Mar 89 14:39:11 EST
From: Guy Steele <gls@Think.COM>
Message-Id: <8903161939.AA05061@verdi.think.com>
To: barmar@Think.COM
Cc: masinter.pa@xerox.com, x3J13@sail.stanford.edu
In-Reply-To: Barry Margolin's message of Thu, 16 Mar 89 12:16 EST <19890316171639.5.BARMAR@OCCAM.THINK.COM>
Subject: Issue: TIME-ZONE-NON-INTEGER, v.1

   Date: Thu, 16 Mar 89 12:16 EST
   From: Barry Margolin <barmar@Think.COM>

       Date: 16 Mar 89 07:07 PST
       From: masinter.pa@xerox.com

       Proposal (TIME-ZONE-NON-INTEGER:ALLOW)

       Specify that the time zone part of Decoded Time is a rational number
       (either an integer or a ratio).

   Just to show you, when I become a billionaire I'll form my own country
   and give it an irrational time zone (e in the winter, sqrt(2) in the
   summer).

   Seriously, is there any particular reason not to allow any non-complex
   number as a time zone?

						   barmar

When you become a billionaire, you'll probably find that
you get a better approximation to e or sqrt(2) with a moby
bignum rational than with a float.

--Quux

∂16-Mar-89  1212	X3J13-mailer 	Issue: COPY-SYMBOL-PRINT-NAME, v.2  
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  12:12:18 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 11:42:46 PST
Date: 16 Mar 89 11:29 PST
From: masinter.pa@Xerox.COM
Subject: Issue: COPY-SYMBOL-PRINT-NAME, v.2
to: X3J13@sail.stanford.edu
line-fold: NO
Message-ID: <890316-114246-4951@Xerox>

!
Issue:        COPY-SYMBOL-PRINT-NAME
References:   COPY-SYMBOL (p. 169)
Category:     CLARIFICATION
Edit history: 1-MAR-89, Version 1 by Chapman
              15-MAR-89, Version 2 by Chapman
 
Problem Description:
 
The description of COPY-SYMBOL states that it "returns a new uninterned
symbol with the same print name as sym (its first argument)". The words
"the same as" are not defined in CLtL. Do they mean EQ, EQUAL, ...?
 
Proposal (COPY-SYMBOL-PRINT-NAME:EQUAL)
 
The description of COPY-SYMBOL should read as follows:
"COPY-SYMBOL returns an uninterned
symbol whose print name is STRING= to
the print name of the symbol that is the first argument to COPY-SYMBOL."
 
Suggested implementation note:
The string should not be copied unnecessarily. In this case, the uninterned
symbol's print name would be EQ to the print name of the argument symbol.
 
Rationale:
 
This clarification resolves any possibility of ambiguity.
 
Current Practice:
 
Medley did this: the symbol names didn't really have a string header and
some symbol names (the "initial symbols" ) had a different place for
storing the actual characters than symbols created later. Unfortunately,
that means that SYMBOL-NAME has to CONS.
It wasn't so much a problem for Interlisp since most of the "string"
functions in Interlisp will take symbols, but in Common Lisp, it is a
performance hit. Poor design, but there's no reason to require SYMBOL-NAME
to return EQ strings. 
In this case, the strings aren't EQ even though the string characters are
shared. (Think of it as strings displaced to a shared area.)
 
 
Adoption Cost:
 
?
 
Benefits:
 
Less ambiguity in the specification, and potentially more portable code.
 
Conversion Cost:
 
?
 
Aesthetics:
 
None.
 
Discussion:
 

∂16-Mar-89  1212	X3J13-mailer 	Issue: COPY-SYMBOL-COPY-PLIST, v.1  
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  12:12:12 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 89 11:27:49 PST
Date: 16 Mar 89 11:27 PST
From: masinter.pa@Xerox.COM
Subject: Issue: COPY-SYMBOL-COPY-PLIST, v.1
To: x3j13@sail.stanford.edu
line-fold: NO
Message-ID: <890316-112749-4871@Xerox>

The only discussion on this issue was whether it was necessary
to clarify (some thought it was) and whether a more general 
"copy the list means COPY-LIST" was necessary (probably not.)

There was no controversy on the proposal itself.

!
Issue:		COPY-SYMBOL-COPY-PLIST
References:	COPY-SYMBOL (p 169), COPY-LIST (p 268), COPY-TREE (p
		269).
Category:	CLARIFICATION
Edit history:	10-Jan-89, Version 1 by Margolin

Problem Description:

The description of COPY-SYMBOL, where the COPY-PROPS optional argument
is non-NIL, says that a copy of the property list is used as the new
symbol's property list.  However, there are several ways in which a list
may be copied, most notably COPY-LIST and COPY-TREE, and the description
doesn't say which mechanism should be used.

Proposal (COPY-SYMBOL-COPY-PLIST:COPY-LIST)

Clarify that when COPY-SYMBOL copies the property list of the symbol, it
is as if (COPY-LIST (SYMBOL-PLIST sym)) were used as the new symbol's
property list.

Rationale:

COPY-LIST is the simplest list-copying primitive.  The result of this
copy is that GET returns EQL results for the two symbols until one of
the property lists is altered, but altering either of the property lists
doesn't affect the other.  This is current practice in the
implementations I tested, and probably what most users assume.

Current Practice:

Symbolics Genera and Sun Common Lisp currently implement this.  I
suspect most others do, too.

Cost to Implementors:

Little or none.

Cost to Users:

None unless they've been assuming some other type of copy.

Benefits:

Less ambiguity.

Aesthetics:

Well, I like it.

∂16-Mar-89  1213	X3J13-mailer   
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  12:12:39 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 89 12:00:57 PST
Date: 16 Mar 89 11:59 PST
From: masinter.pa@Xerox.COM
To: X3J13@sail.stanford.edu
line-fold: NO
Message-ID: <890316-120057-5042@Xerox>

I think this is one of the more important issues to consider,
in that it is addresses one of the most frequently noted
performance issues in Common Lisp. We've examined a large number
of proposals and alternatives to allow declaration of dynamic extent 
in Common Lisp.

!
Forum:	CLEANUP
Issue:          DYNAMIC-EXTENT
References:     Scope and Extent
Category:       ADDITION
Edit history:   27-Jun-88, Version 1 by Pitman (as issue STACK-LET)
		15-Nov-88, Version 2 by Pitman (issue renamed, major revision)
		11-Jan-89, Version 3 by Masinter (Moon's proposal)
Related-Issues: REST-ARGUMENT-EXTENT, WITH-DYNAMIC-EXTENT

Problem Description:

  Sometimes a programmer knows that a particular data structure
  will have only dynamic extent. In some implementations, it is
  possible to allocate such structures in a way that will make them
  easier to reclaim than by general purpose garbage collection
  (eg, on the stack or in some temporary area). Currently, however,
  there is no way to request the use of such an allocation mechanism.

Proposal (DYNAMIC-EXTENT:NEW-DECLARATION):

  Introduce a new declaration called DYNAMIC-EXTENT. The arguments to
  this declaration are names of variables. The declaration asserts that
  the value which is initially held by the indicated variable will have
  dynamic extent. [In the case of an iteration variable, the declaration
  asserts that on every iteration, the initial value of that variable
  for the iteration will have dynamic extent.]

  It is permissible for an implementation to simply ignore this declaration.
  In implementations which do not ignore it, the compiler (or interpreter)
  is free to make whatever optimizations are appropriate given this
  information; the most common optimization is to stack-allocate the
  initial value of the object. What data types (if any) can have dynamic
  extent will can vary from implementation to implementation.

  Since stack allocation of the initial value entails knowing at the
  object's creation time that the object can be stack-allocated, it is
  not generally useful to declare DYNAMIC-EXTENT for variables for
  which have no lexically apparent initial value. For example,

	(DEFUN F ()
	  (LET ((X (LIST 1 2 3)))
	    (DECLARE (DYNAMIC-EXTENT X))
	    ...))

  would permit those compilers which wish to do so to stack-allocate the
  list in X. However,

	(DEFUN G (X) (DECLARE (DYNAMIC-EXTENT X)) ...)
	(DEFUN F () (G (LIST 1 2 3)))

  could not typically permit a similar optimization in G because it would
  be a modularity violation for the compiler to assume facts about G from
  within F. Only an implementation which was willing to be responsible for
  recompiling F if G's definition changed incompatibly could stack-allocate
  the list argument to G in F.

  Other interesting cases are:

	(PROCLAIM '(INLINE G))
	(DEFUN G (X) (DECLARE (DYNAMIC-EXTENT X)) ...)
	(DEFUN F () (G (LIST 1 2 3)))

    and	(DEFUN F ()
	  (FLET ((G (X) (DECLARE (DYNAMIC-EXTENT X)) ...))
	    (G (LIST 1 2 3))))

  where some compilers might realize the optimization was possible and others
  might not.

  An interesting variant of this is the so-called `stack allocated rest list'
  which can be achieved (in implementations supporting the optimization) by:

	(DEFUN F (&REST X)
	  (DECLARE (DYNAMIC-EXTENT X))
	  ...)

  Note here that although the initial value of X is not explicit, the F
  function is responsible for assembling the list X from the passed arguments,
  so the F function can be optimized by the compiler to construct a 
  stack-allocated list instead of a heap-allocated list in implementations
  which support such.

   The meaning of a dynamic extent declaration is that execution of the
   forms in the scope of the declaration will not "save" any "proper part"
   of the initial value of the declared variable.  To "save" an object
   means to cause a reference to that object to be accessible outside the
   dynamic extent of the form at the beginning of whose body the
   declaration appears.  An object can be "saved" by storing it with a
   side-effecting operation and not replacing it with a different value
   before the end of the dynamic extent, by using it as a component of a
   freshly-allocated object that is itself "saved," by capturing it in a
   function closure that is itself "saved," by returning it as a value, or
   by transmitting it outside the dynamic extent with THROW.  A "proper
   part" of an object A is any object that is accessible at the beginning
   of the scope of the declaration -only- by applying a function to A or to
   a "proper part" of A.  This means that any objects freshly allocated
   during the construction of the initial value of the declared variable,
   and not "saved" during the construction of that value, are "proper
   parts" and can be allocated on a stack.

Examples:

In
            (LET ((X (LIST 'A1 'B1 'C1))
                  (Y (CONS 'A2 (CONS 'B2 (CONS 'C2 NIL)))))
              (DECLARE (DYNAMIC-EXTENT X Y))
              ...)
The "proper parts" of X are three conses, and the "proper parts" of Y
are three other conses.  None of the symbols A1, B1, C1, A2, B2, C2, or
NIL is a "proper part" of X or Y.  However, if a freshly allocated
uninterned symbol had been used, it would have been a "proper part."

- - - - - - - -
          (DOTIMES (I N) 
            (DECLARE (DYNAMIC-EXTENT I))

This is particularly instructive.  Since I is an integer by the
definition of DOTIMES, but EQ and EQL are not necessarily equivalent for
integers, what are the "proper parts" of I, which this declaration
requires the body of the DOTIMES not to "save"?  If the value of I is 3,
and the body does (SETQ FOO 3), is that an error?  The answer is no, but
the interesting thing is that it depends on the implementation-dependent
behavior of EQ on numbers.  In an implementation where EQ and EQL are
equivalent for 3, then 3 is not a "proper part" because (EQ I (+ 2 1))
is true, and therefore there is another way to access the object besides
going through I.  On the other hand, in an implementation where EQ and
EQL are not equivalent for 3, then the particular 3 that is the value of
I is a "proper part", but any other 3 is not.  Thus (SETQ FOO 3) is valid
but (SETQ FOO I) is erroneous.  Since (SETQ FOO I) is erroneous in some
implementations, it is erroneous in all portable programs, but some other
implementations may not be able to detect the error.

- - - - - - - -

  (LET ((X (LIST 1 2 3)))
    (DECLARE (DYNAMIC-EXTENT X))
    (PRINT X)
    NIL)
  PRINT does not "save" any part of its input.
  This prints (1 2 3)

- - - - - - - -

  (DO ((L (LIST-ALL-PACKAGES) (CDR L)))
      ((NULL L))
    (DECLARE (DYNAMIC-EXTENT L))
    (PRINT (CAR L)))
  prints all packages; none of the newly-allocated list structures are saved.
- - - - - - - -
  (DEFUN ADD (&REST X) (DECLARE (DYNAMIC-EXTENT X)) (APPLY #'+ X))
  (ADD 1 2 3) => 6

I.e., useful way to declare that &REST lists have dynamic extent
- - - - - - - -
  (DEFUN ZAP (X Y Z)
    (DO ((L (LIST X Y Z) (CDR L)))
	((NULL L))
      (DECLARE (DYNAMIC-EXTENT L))
      (PRIN1 (CAR L))))
  (ZAP 1 2 3)
  prints 123

- - - - - - - -
  (DEFUN ZAP (N M)
    ;; Computes (RANDOM (+ M 1)) at relative speed of roughly O(N).
    ;; It may be slow, but with a good compiler at least it
    ;; doesn't waste much heap storage.  :-)
    (LET ((A (MAKE-ARRAY N)))
      (DECLARE (DYNAMIC-EXTENT A))
      (DOTIMES (I N) 
	(DECLARE (DYNAMIC-EXTENT I))
	(SETF (AREF A I) (RANDOM (+ I 1))))
      (AREF A M)))
  (< (ZAP 5 3) 3) => T

- - - - - - - -
The following are in error, since the value of X is used outside of its
extent:

       (LENGTH (LIST (LET ((X (LIST 1 2 3))) (DECLARE (DYNAMIC-EXTENT X)) X)))

  (PROGN (LET ((X (LIST 1 2 3))) (DECLARE (DYNAMIC-EXTENT X)) X)
         NIL)

- - - - - - - -

Rationale:

  This permits a programmer to offer advice to an implementation about
  what may be stack-allocated for efficiency.

  It may be difficult or impossible for a compiler to infer this
  same information statically.

  Since a number of implementations offer this capability and there
  is demand from users for access to the capability, this ``codifies
  existing practice.''

  Because this approach is purely lexical, it does not interact badly with
  other programs in the way that the macro WITH-DYNAMIC-EXTENT (see issue
  by same name) would.

Current Practice:

  Symbolics Genera and Symbolics Cloe offer stack allocation, though not
  in this strategy.

  [KMP thinks that] Lucid supports the proposal.

Cost to Implementors:

  No cost is forced since implementations are permitted to simply
  ignore the DYNAMIC-EXTENT declaration.

Cost to Users:

  None. This change is upward compatible.

  There may be some hidden costs to debugging using this declaration (or any
  feature which permits the user to access dynamic extent objects without
  the compiler proving that they are appropriate). If the user misdeclares
  something and returns a pointer into the stack (or stores it in the heap),
  an undefined situation may result and the integrity of the Lisp storage
  mechanism may be compromised. Debugging these situations may be tricky,
  but users who have asked for this feature have indicated a willingness
  to deal with such costs. Nevertheless, the perils should be clearly
  documented and casual users should not be encouraged to use this
  declaration.

Cost of Non-Adoption:

  Some portable code would be forced to run more slowly (due to
  GC overhead), or to use non-portable language features.

Benefits:

  The cost of non-adoption is avoided.

Aesthetics:

  This declaration allows a fairly low level optimization to work
  by asking the user to provide only very high level information.
  The alternatives (sharpsign conditionals, some of which may
  lead to more bit-picky abstractions) are far less aesthetic.

Discussion:

  A previous version of this proposal suggested primitives STACK-LET
  and STACK-LET*. Consensus was that the more general declaration facility
  would be more popular.

  Pitman supports the DYNAMIC-EXTENT:NEW-DECLARATION.

  Actually, a blurry issue is whether
   (LENGTH (LIST (LET ((X (LIST 1 2 3))) (DECLARE (DYNAMIC-EXTENT X)) X)))
   => 1
  is well-defined. I refer to these stack-allocated things as being invalid
  return values, but in fact we might want to say that they're ok to return
  but that you just can't do any serious operations on them (ie, you can't
  expect them to still be lists, etc.) Can anyone imagine a pointer into
  unallocated stack causing problems for their GC? If so, we could be more
  clear on this point.

The examples are tricky:

"I hope no one misreads the above as an argument that my proposal is too
complicated, since it does not derive at all from my proposal, but only
from the way Common Lisp works."


!
Additional comments:

... I really like this rewrite a lot. It's quite
clever in the way it presents things in order to get additional flexibility.

However, I do have a few comments I'd like to see addressed before this
gets to a vote...

 * I like the concept "proper part" a lot but I don't like the name.
   The term "proper" for proper lists has to do with well-formed-ness
   and in this context you're suggesting an incompatible meaning which
   is confusing.
   
   I suggest instead a term like "internal", "intrinsic", "private",
   "unshared", etc.
   
   [The concept of "unshared" makes me immediately scared about the
    whole quote-may-copy morass, but I don't have time to think through
    right now whether that's an issue that needs further clarification
    or if it's just a red herring.]

 * I like the concept of "saved" but it has the problem that it isn't
   easy to bring up "out of context" since "save" has a lot of connotations.
   If it were possible to come up with a more unique term, I think it
   would help in lunch table conversations when people start getting
   screwed by things that were `unintentionally saved' and others can't
   figure out what they mean out of context.

 * I think your list of definitions for saved is pretty good, but I'd
   still like to see an abstract definition, and then the concrete cases
   listed beneath it. That way, we are protected from weird unintentional 
   interpretations if someone discovers that the set was not exhaustive
   and needs to include their new case under the abstract description
   because the concrete list doesn't accomodate things.

 * What about things like:

   (DEFUN FOO (&REST X)
     (DECLARE (DYNAMIC-EXTENT X))
     (MAPL #'PRINT X)
     T)

   Genera's Dynamic Windows (DW) had bugs in its first release because the
   window history recorded the object which was printed. Put another 
   way, PRINT did unexpected "saving" on some streams. The situation with
   DW was treated as a bug and now DW correctly detects stack-allocated
   things and does not try to save them, so this would work now.
   However, it still raises the question of whether we should define
   per-function for every CL function whether any of the arguments is
   permitted to be "saved" so that CL programs don't get any funny surprises.
   If we don't, it ends up being implementor's discretion how to resolve
   cases like this, and everyone might not agree that all cases are as 
   obvious as this one was.

- - - - - - -
re:  However, it still raises the question of whether we should define
     per-function for every CL function whether any of the arguments is
     permitted to be "saved" so that CL programs don't get any funny surprises.
     If we don't, it ends up being implementor's discretion how to resolve
     cases like this, and everyone might not agree that all cases are as 
     obvious as this one was.

PDP10 MacLisp had a similar problem w.r.t pdlnums.  That is why
"identity" functions were so troublsome for it -- in order to
return a guaranteed safe value, it typically had to copy it's
pdlnum argument, thereby making some cases of "fast arithmetic" 
code much worse than interpreted code!  [Remember PRINT in MacLisp?
it returns T rather than it's argument for just this reason.]

It is necessary for an optimizing compiler to know something about
what happens to the data it passes along to "system" functions; for
example, it could assume that GET doesn't clobber the list given
to it, nor does it retain pointers to any part of it [what was the
terminology in the revised proposal?  "saved"? and "proper part"?]
The issue LISP-SYMBOL-REDEFINITION might help here, in that an
implementation's compilers could depend upon it's own internal
database.  But it wouldn't hurt at all to have some of these
requirements "up front" in the standard.

∂16-Mar-89  1212	X3J13-mailer 	*DRAFT* Issue: DESTRUCTURING-BIND, v.2   
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  12:12:27 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 11:49:11 PST
Date: 16 Mar 89 11:46 PST
From: masinter.pa@Xerox.COM
Subject: *DRAFT* Issue: DESTRUCTURING-BIND, v.2
to: X3J13@sail.stanford.edu
line-fold: NO
Message-ID: <890316-114911-4982@Xerox>

This issue is draft; there will hopefully be a new version before
the meeting. 

The discussion centers around what lambda-list keywords should be
allowed.

&ENVIRONMENT:
	everybody says disallow

&WHOLE:
	Moon said allow (the second time.)

NIL:
	Moon says allow as a way of ignoring.
	KMP says OK, maybe in other places too.
	Discussion of IGNORE led to new issue.

&BODY:
	KMP makes case for disallowing, but says
	allow.

There was some additional discussion that resulted in the
related issues of DEFMACRO-LAMBDA-LIST and IGNORE-VARIABLE.

I'd be happy with a proposal that said NIL is ignored,
 &WHOLE and &BODY are allowed, and that &ENVIRONMENT 
is disallowed. I'd like to make sure it was consistent
with LOOP.
!
Issue:        DESTRUCTURING-BIND
Forum:	      Cleanup
References:   DEFMACRO (CLtL pp145-151),
	      The LOOP Facility (X3J13/89-004)
Category:     ADDITION
Edit history: 24-Jan-89, Version 1 by Pitman
	      25-Jan-89, Version 2 by Pitman
Status:	      For Internal Discussion

Problem Description:

  Common Lisp programmers have frequently complained that the
  destructuring facility used by DEFMACRO is not made available
  for use in ordinary programming situations involving list data.

  The presence of a destructuring facility in the recently adopted
  LOOP facility will be likely to make the absence of a separable
  destructuring facility all the more apparent.

  Prior to the introduction of LET into Maclisp, many people wrote
  their own LET macros. A popular expansion was in terms of a DO
  which did not iterate. eg,
    (LET ((A 3)) (+ A A)) ==> (DO ((A 3)) () (RETURN (+ A A)))
  While this practice `worked,' it was not perspicuous and contributed 
  substantially to non-readability: not only were the macros hard to
  understand, but the surface interface itself was not standardized
  and varied in subtle ways. For example, some LET macros allowed GO
  statements while others did not.

  There is now considerable danger that a lot of people will write
  DESTRUCTURING-BIND variants in terms of a LOOP expression that
  immediately returns.
    (DESTRUCTURING-BIND ((A B) C) (FOO) (LIST A B C))
    ==> (LOOP FOR ((A B) C) ON (FOO) DO (RETURN (LIST A B C)))
  Since the destructuring offered by LOOP is different in subtle ways
  from the destructuring offered by DESTRUCTURING-BIND in implementations
  offering that primitive natively, gratuitous headaches could result.

Proposal (DESTRUCTURING-BIND:NEW-MACRO):

  Provide a macro called DESTRUCTURING-BIND which behaves like the
  destructuring bind in DEFMACRO. Specifically...

  DESTRUCTURING-BIND lambda-list expression {decl|doc}* {form}*   [Macro]

   Binds the variables specified in LAMBDA-LIST to the corresponding
   values in the tree structure resulting from evaluating EXPRESSION,
   then evaluates the FORMS in the body.

   Anywhere in the LAMBDA-LIST where a parameter name may appear, and
   where ordinary lambda-list syntax (as described in CLtL section 5.2.2)
   does not otherwise allow a list, a lambda-list may appear in place of
   the parameter name. When this is done, then the argument form that
   would match the parameter is treated as a (possibly dotted) list, to
   be used as an argument forms list for satisfying the parameters in
   the embedded lambda-list.

   If any of the lambda list keywords &OPTIONAL, &REST, &KEY,
   &ALLOW-OTHER-KEYS and &AUX appears in the lambda list, it is treated
   as with any other lambda-list.

   If the lambda list keyword &BODY appears, it is treated as a synonym
   for &REST.

   If the lambda list keyword &WHOLE appears, it must be followed by a
   single variable that is bound to the entire expression at the current
   level. &WHOLE and the following variable should appear first in the
   list, before any other parameter or lambda-list keyword.

   It is also permissible for any level of the LAMBDA-LIST to be dotted,
   ending in a parameter name. This situation is treaed exactly as if
   the aprameter name that ends the list had appeared preceded by &REST
   in a proper list. For example, the notation (X Y . Z) is equivalent
   to (X Y &REST Z).

   If the result of evaluating the expression does not match the 
   destructuring pattern, the consequences are undefined. Implementations
   are not required to signal an error in this case, but neither are they
   permitted to extend the behavior by defining it to be harmless.

  Clarify that the destructuring done by LOOP does not permit the use of
  any lambda-list-keywords. Further clarify that in LOOP, proper lists
  are implicitly `&REST var' (where the non-use of var is quietly ignored).
  Hence, it is permissible to have:
    (LOOP FOR (X Y) ON '(A B C D) COLLECT (CONS X Y)) => ((A . B) (C . D))
  but it is not permissible to have:
    (DESTRUCTURING-BIND (X Y) '(A B C D) (CONS X Y))
  since the pattern does not match. One must instead write:
    (DESTRUCTURING-BIND (X Y &REST Z) '(A B C D) 
      (DECLARE (IGNORE Z))
      (CONS X Y))

Test Case:

  (DEFUN IOTA (N) (LOOP FOR I FROM 1 TO N COLLECT I)) ;helper

  (DESTRUCTURING-BIND ((A &OPTIONAL (B 'BEE)) ONE TWO THREE)
		      `((ALPHA) ,@(IOTA 3))
    (LIST A B THREE TWO ONE))
  => (ALPHA BEE 3 2 1)

Rationale:

  The proposal directly addresses the stated problem, and is current practice
  in numerous implementations. Our charter effectively dictates that where
  feasible we should try to head off the widespread development of uselessly
  different variants of commonplace tools.

Current Practice:

  Symbolics Genera, Envos Medley, TI Explorer, and Lucid CL all offer
  DESTRUCTURING-BIND, though the details vary slightly.

  The DESTRUCTURING-BIND offered by Symbolics Genera signals an error if
  the pattern is not matched. The TI Explorer version does not.

Cost to Implementors:

  Very small. In most cases, it's a matter of renaming and/or exporting an
  already existing symbol. In a few cases, a very small amount of 
  `program interface' code would have to be written.

Cost to Users:

  None. This is an upward compatible change.

Cost of Non-Adoption:

  Loss of the Benefits and Aesthetics cited below.

Benefits:

  Users will get a powerful feature they have asked for on many occassions.

  In implementations which `autoload' code, it would be better for this
  support to be separable so that people could do DESTRUCTURING-BIND
  without demand loading all other LOOP support.

Aesthetics:

  Defining this macro centrally for the Common Lisp community will reduce
  subtle deviations, which will in turn have positive aesthetic impact.

Discussion:

  JonL observes that although LOOP does destructuring, it can't directly
  make use of the DESTRUCTURING-BIND interface suggested here.

  Pitman and Gray think a facility of this sort is a good idea, though
  obviously the details may still need a little fleshing out before the
  proposal is ready for vote.

  To date, the excuse for not satisfying this request has been a
  religious war between factions who want to destructure lists by
  writing
    (DESTRUCTURING-BIND (var1 var2 var3) exp . body)
  and those who want to destructure lists by writing
    (DESTRUCTURING-BIND (LIST var1 var2 var3) exp . body)

  The advantage of the former approach is that it is notationally
  concise for the common case of destructuring a list. The disadvantage
  is that it is not extensible to accomodate abstract kinds of
  destructuring.

  The advantage of the latter approach is that it allows interesting
  extensions that accomodate data-hiding, such as:
    (DEFMACRO MAKE-FOO (&REST ELEMENTS) `(LIST ,@ELEMENTS))
    (DESTRUCTURING-BIND (MAKE-FOO var1 var2 var3) exp . body)
  and later the ability to change the representation of a FOO without
  updating the associated binding forms. The disadvantage is that it
  is more verbose in the common case of destructuring a list, and still
  even more verbose for nested lists.

  Although destructuring has always existed in DEFMACRO, this has not
  been adequate precedence for deciding the outcome of the religious war
  because DEFMACRO only needs to destructure programs, and programs are
  generally made up only of lists -- not arbitrary user-defined abstract
  data types.

∂16-Mar-89  1221	X3J13-mailer 	Issue DESCRIBE-UNDERSPECIFIED, v.1  
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 16 Mar 89  12:20:58 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 558750; Thu 16-Mar-89 15:18:32 EST
Date: Thu, 16 Mar 89 15:18 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue DESCRIBE-UNDERSPECIFIED, v.1
To: masinter.pa@Xerox.COM, Kim A. Barrett <IIM@ECLA.USC.EDU>
cc: x3j13@SAIL.STANFORD.EDU
In-Reply-To: <890316-082029-3881@Xerox>
Message-ID: <19890316201824.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

I think this is unnecessary, but I do not strongly oppose it.
The proposed division of labor between the DESCRIBE function and
the DESCRIBE-OBEJCT generic function could be implemented by
an :AROUND method for the existing DESCRIBE generic function.
The claim that binding *STANDARD-OUTPUT* is dangerous in the
presence of interrupts is false, since many things bind
*STANDARD-OUTPUT* and any reasonable interactive interrupt
handler must rebind the standard streams, the print control
variables, etc.

I don't strongly oppose this since it might be worthwhile just
for the symmetry with the PRINT-OBJECT generic function.

∂16-Mar-89  1241	X3J13-mailer 	Issue DYNAMIC-EXTENT: a remark 
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  12:41:00 PST
Received: from fafnir.think.com by Think.COM; Thu, 16 Mar 89 15:36:50 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Thu, 16 Mar 89 15:38:04 EST
Received: by verdi.think.com; Thu, 16 Mar 89 15:34:53 EST
Date: Thu, 16 Mar 89 15:34:53 EST
From: Guy Steele <gls@Think.COM>
Message-Id: <8903162034.AA05881@verdi.think.com>
To: masinter.pa@xerox.com
Cc: X3J13@sail.stanford.edu
In-Reply-To: masinter.pa@xerox.com's message of 16 Mar 89 11:59 PST <890316-120057-5042@Xerox>
Subject: Issue DYNAMIC-EXTENT: a remark


This is the last paragraph of the proposal DYNAMIC-EXTENT:NEW-DECLARATION:

      The meaning of a dynamic extent declaration is that execution of the
      forms in the scope of the declaration will not "save" any "proper part"
      of the initial value of the declared variable.  To "save" an object
      means to cause a reference to that object to be accessible outside the
      dynamic extent of the form at the beginning of whose body the
      declaration appears.  An object can be "saved" by storing it with a
      side-effecting operation and not replacing it with a different value
      before the end of the dynamic extent, by using it as a component of a
      freshly-allocated object that is itself "saved," by capturing it in a
      function closure that is itself "saved," by returning it as a value, or
      by transmitting it outside the dynamic extent with THROW.  A "proper
      part" of an object A is any object that is accessible at the beginning
      of the scope of the declaration -only- by applying a function to A or to
         ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
      a "proper part" of A.  This means that any objects freshly allocated
      during the construction of the initial value of the declared variable,
      and not "saved" during the construction of that value, are "proper
      parts" and can be allocated on a stack.

I believe that the words indicated above should be replaced by
"the extent of the binding for which the delaration was made".
The reference appears to be to a point in time.  Scopes are in space;
the beginning of a scope is a character position in the text (or
something like that).  Extents are in time.  Is this what you meant?

--Conan the Pedantrian  (a.k.a. Guy)

∂16-Mar-89  1436	X3J13-mailer 	Fatal vesus Harmless 
To:   x3j13@SAIL.Stanford.EDU
CC:   cl-editorial@SAIL.Stanford.EDU 
From: Dick Gabriel <RPG@SAIL.Stanford.EDU>


This is my last attempt at making my argument. I don't think there is much
else I can say to persuade you.

I wrote:

``The definition of fatal puts no time constraints on the fatality. Therefore,
neither does its negation.''

Let's define the term ``win'' to mean ``doesn't crash or abnormally
terminate''; basically, it is the bad case that the definition of
``fatal'' talks about.  Let ``lose'' mean ``not win.''

Here are two partially formal definitions of ``fatal'' and ``harmless.''

The program P has consequences that are fatal if there
exists a sequence of conforming programs, P1,...,Pj,Pj+1,...,Pn, where
(progn P1...Pn) wins, but (progn P1...Pj P Pj+1...Pn) loses.

That is, the execution of P eventually leads to fatality in some program.

The program P has consequences that are harmless if
for all sequences of conforming programs, P1,...,Pj,Pj+1,...,Pn, where
(progn P1...Pn) wins, (progn P1...Pj P Pj+1...Pn) also wins.

That is, the execution of P never leads to fatality in any program.

There might be an infinite amount of hair to make this precise, but that's
the idea.  And, there is some question about how different we allow the
behavior of the programs with P to be from the behavior of the programs
without P.  (The language of the definitions of these terms are meant to
warn people to beware that behavior is in jeopardy.)  But, the terms are
related by a negation with respect to the degree to which they are
well-defined.

I think part of the problem of understanding comes from the question of
side effects noticeable to conforming programs. A program with harmless
consequences can have side effects; notice our partly formal definition
doesn't say anything about what the programs do.

We all believe harmless a garbage collector that moves objects from place
to place where the movement is unnoticeable by conforming programs. Probably
most of us believe harmless a garbage collector whose progress is displayed.

I think none of us believes harmless a garbage collector that sets to
NIL all property lists of symbols in the USER package.

I think most of use believe harmful a garbage collector that changes the
order of properties on property lists.

However, consider an implementation of Common Lisp that uses a very hairy
representation for property-list lists. These lists have the feature that
sometimes the garbage collector will re-order their properties according
to some LRU bits to aid performance. Of course, through extreme hair, the
GC won't change the order if some piece of the property list is stored
somewhere other than the property list itself. Think of it as an
optimization that is conservatively performed.

Nowhere does the CL specification state that the order of properties
remains constant if the property list is not explicitly altered.  Do those
of us who believed harmful the GC that changed property list order believe
this GC harmful? Or did some of us change our votes?

Suppose we alter the definition of symbol-plist from this:

``This returns *the* list the contains the property pairs of <symbol>;
the contents of the property-list cell are *extracted* and returned.''

to this:

``This returns *a* list the contains the property pairs of <symbol>;
the contents of the property-list cell are *copied* and returned.''

Now does the order-changing GC seem more harmless? It certainly has
less transparent behavior.

Suppose we explicitly specified that the order of properties on a property
list could change from time to time, possibly by GC actions. We have
defined the GC to be non-transparent, but is it harmless?

The sense of the definitions come from the partially formal definitions.
I think these definitions are pesuasive regarding the usefulness of a
term like ``harmless.''

I believe those definitions are difficult to make formal without some
very detailed computational or semantic model. The series of strange
GC behaviors with respect to property lists should make us leery of
making these definitions too precise at the expense of deciding these
cases one way when in five years we will wish we could decide them
the other way.

Specifications such as the one we are writing are communications
among people, and therefore absolute precision is impossible without
overspecification.

			-rpg-

∂16-Mar-89  1418	X3J13-mailer 	Issue DYNAMIC-EXTENT: a remark 
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 16 Mar 89  14:18:09 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 558915; Thu 16-Mar-89 17:15:26 EST
Date: Thu, 16 Mar 89 17:15 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue DYNAMIC-EXTENT: a remark
To: Guy Steele <gls@Think.COM>
cc: masinter.pa@xerox.com, X3J13@sail.stanford.edu
In-Reply-To: <8903162034.AA05881@verdi.think.com>
Message-ID: <19890316221519.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: Thu, 16 Mar 89 15:34:53 EST
    From: Guy Steele <gls@Think.COM>

	  A "proper
	  part" of an object A is any object that is accessible at the beginning
	  of the scope of the declaration -only- by applying a function to A or to
	     ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
	  a "proper part" of A.  This means that any objects freshly allocated
	  during the construction of the initial value of the declared variable,
	  and not "saved" during the construction of that value, are "proper
	  parts" and can be allocated on a stack.

    I believe that the words indicated above should be replaced by
    "the extent of the binding for which the delaration was made".

That would change the meaning, since the declaration might not be attached
to a binding.

    The reference appears to be to a point in time.  Scopes are in space;
    the beginning of a scope is a character position in the text (or
    something like that).  Extents are in time.  Is this what you meant?

You're right that there is something wrong with this wording.  How about
if it said "at the beginning of execution of the forms in the scope of
the declaration"?  Do declarations have extents?  If so, could it say
"at the beginning of the extent of the declaration"?

∂16-Mar-89  1424	X3J13-mailer 	Issue: TIME-ZONE-NON-INTEGER, v.1   
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 16 Mar 89  14:23:49 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 558923; Thu 16-Mar-89 17:20:36 EST
Date: Thu, 16 Mar 89 17:20 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: TIME-ZONE-NON-INTEGER, v.1
To: barmar@Think.COM
cc: Guy Steele <gls@Think.COM>, masinter.pa@xerox.com, x3J13@sail.stanford.edu
In-Reply-To: <8903161939.AA05061@verdi.think.com>
Message-ID: <19890316222034.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: Thu, 16 Mar 89 14:39:11 EST
    From: Guy Steele <gls@Think.COM>

       Date: Thu, 16 Mar 89 12:16 EST
       From: Barry Margolin <barmar@Think.COM>

	   Date: 16 Mar 89 07:07 PST
	   From: masinter.pa@xerox.com

	   Proposal (TIME-ZONE-NON-INTEGER:ALLOW)

	   Specify that the time zone part of Decoded Time is a rational number
	   (either an integer or a ratio).

       Just to show you, when I become a billionaire I'll form my own country
       and give it an irrational time zone (e in the winter, sqrt(2) in the
       summer).

    When you become a billionaire, you'll probably find that
    you get a better approximation to e or sqrt(2) with a moby
    bignum rational than with a float.

As a billionaire, you'll be able to afford to do all your processing
with indefinite-precision exact arithmetic.

Does Guy have inside information on when Barry will become a billionaire?

∂16-Mar-89  1443	CL-Compiler-mailer 	Re: issue COMPILED-FUNCTION-REQUIREMENTS, version 4    
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 16 Mar 89  14:43:02 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 558959; Thu 16-Mar-89 17:39:16 EST
Date: Thu, 16 Mar 89 17:39 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: issue COMPILED-FUNCTION-REQUIREMENTS, version 4
To: Barry Margolin <barmar@FAFNIR.THINK.COM>
cc: masinter.pa@xerox.com, cl-compiler@sail.stanford.edu, X3J13@sail.stanford.edu
In-Reply-To: <19890316173142.7.BARMAR@OCCAM.THINK.COM>
Message-ID: <19890316223916.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: Thu, 16 Mar 89 12:31 EST
    From: Barry Margolin <barmar@FAFNIR.THINK.COM>

    I'll just reiterate something I said at one of the meetings.  One
    portable use I can think of for the COMPILED-FUNCTION type is as a
    declaration to allow compiler optimization.  If a function knows (or
    requires) that a parameter is a compiled function it can declare that
    and the implementation may be able to optimize the FUNCALL better.

But as someone said the last time this suggestion was brought up, if
there is no portable meaning of the COMPILED-FUNCTION type and no
portable way to create an object of that type, no useful correct program
can contain this declaration.

    Another thing I just thought of is something like:

	    (when (typep f '(and function (not compiled-function)))
	      (setq f (compile nil f)))

    This doesn't actually work because COMPILE isn't required to accept
    lexical closures

You just glimpsed the tip of the iceberg.

∂16-Mar-89  1354	X3J13-mailer 	Issue: DYNAMIC-EXTENT
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  13:54:21 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Thu, 16 Mar 89 16:49:45 EST
Date: Thu, 16 Mar 89 16:50 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Issue: DYNAMIC-EXTENT
To: masinter.pa@xerox.com
Cc: X3J13@sail.stanford.edu
In-Reply-To: <890316-120057-5042@Xerox>
Message-Id: <19890316215008.1.BARMAR@OCCAM.THINK.COM>

    re:  However, it still raises the question of whether we should define
	 per-function for every CL function whether any of the arguments is
	 permitted to be "saved" so that CL programs don't get any funny surprises.
	 If we don't, it ends up being implementor's discretion how to resolve
	 cases like this, and everyone might not agree that all cases are as 
	 obvious as this one was.
    ...
    It is necessary for an optimizing compiler to know something about
    what happens to the data it passes along to "system" functions; for
    example, it could assume that GET doesn't clobber the list given
    to it, nor does it retain pointers to any part of it [what was the
    terminology in the revised proposal?  "saved"? and "proper part"?]
    The issue LISP-SYMBOL-REDEFINITION might help here, in that an
    implementation's compilers could depend upon it's own internal
    database.  But it wouldn't hurt at all to have some of these
    requirements "up front" in the standard.

I don't think that solves the problem.  Yes, in a system where PRINT
saves its argument the compiler could detect that in

	(defun print-em (&rest stuff)
	  (declare (dynamic-extent stuff))
	  (print stuff))

the declaration is obviously in error and may be ignored (or it might
generate a warning).  In the case of Genera Dynamic Windows, whether
PRINT saves is actually an attribute of the stream, so it is
questionable whether the compiler should override the declaration
(perhaps the programmer knows that the function will only be called with
*STANDARD-OUTPUT* bound to a non-saving stream).  Also, what about the
function

	(defun process-em (&rest stuff)
	  (declare (dynamic-extent stuff))
	  (frobnicate stuff))

If FROBNICATE hasn't been written yet the compiler has no way of
knowing whether it calls any system functions that save the argument.

I think that if we really want this declaration (and I'd like to see it
included, as it is the right compromise for a long-standing problem) we
MUST say something about passing dynamic data to standard functions.  I
think it would be sufficient to say that if the standard doesn't specify
that an argument must be saved then a dynamic object must be acceptable.
In other words, if a user reading the standard can't infer that an
argument will be saved then a conforming program may pass dynamic data
in that argument.  This means that PRINT must accept a dynamic object,
and it is the implementation's responsibility to solve the potential
problems if it normally saves what PRINT prints.

                                                barmar

∂16-Mar-89  1356	CL-Compiler-mailer 	Issue SAFE-CODE, version 1         
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 16 Mar 89  13:56:46 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 558883; Thu 16-Mar-89 16:53:42 EST
Date: Thu, 16 Mar 89 16:53 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue SAFE-CODE, version 1         
To: Dick Gabriel <RPG@SAIL.Stanford.EDU>, masinter.pa@Xerox.COM
cc: cl-compiler@SAIL.Stanford.EDU, x3j13@SAIL.Stanford.EDU
In-Reply-To: <svXEG@SAIL.Stanford.EDU>,
             <890316-070317-3708@Xerox>,
             <1avs40@SAIL.Stanford.EDU>,
             <19890314214907.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890316215335.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

Either "nonsafe code" or "code not declared safe" has better connotations
for me than "unsafe code."  I don't really want to get too deeply involved
in choosing the terminology here (if I did, I would be on the editorial
committee), I only wanted to point out that the word used in version 1
of the proposal had an unwanted connotation for me.

∂16-Mar-89  1551	X3J13-mailer 	Issue: COERCE-INCOMPLETE (Version 3)
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  15:51:26 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Thu, 16 Mar 89 17:59:11 EST
Date: Thu, 16 Mar 89 18:00 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Issue: COERCE-INCOMPLETE (Version 3)
To: masinter.pa@xerox.com
Cc: x3j13@sail.stanford.edu
In-Reply-To: <890316-095901-4371@Xerox>
Message-Id: <19890316230020.6.BARMAR@OCCAM.THINK.COM>

There's an inconsistency in the names of the proposals.  In the Proposal
sections, the two proposals are named LIMITED-ARBITRARY-EXTENSION and
DEPRECATE.  But in some other sections they are called COERCE and
DEPRECATE.

Problem with DEPRECATE: Didn't we specify that the way to convert a
lambda expression into a function object is to use (COERCE x 'FUNCTION)?
Or did we also define a new function that does this?

                                                barmar

∂16-Mar-89  1603	X3J13-mailer 	*DRAFT* Issue: DESTRUCTURING-BIND, v.2   
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  16:02:40 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Thu, 16 Mar 89 17:45:15 EST
Date: Thu, 16 Mar 89 17:46 EST
From: Barry Margolin <barmar@Think.COM>
Subject: *DRAFT* Issue: DESTRUCTURING-BIND, v.2
To: masinter.pa@xerox.com
Cc: X3J13@sail.stanford.edu
In-Reply-To: <890316-114911-4982@Xerox>
Message-Id: <19890316224608.4.BARMAR@OCCAM.THINK.COM>

    Date: 16 Mar 89 11:46 PST
    From: masinter.pa@xerox.com

    Current Practice:

      The DESTRUCTURING-BIND offered by Symbolics Genera signals an error if
      the pattern is not matched. The TI Explorer version does not.

Actually, Genera offers TWO versions of DESTRUCTURING-BIND:
SYMBOLICS-COMMON-LISP:DESTRUCTURING-BIND and
ZETALISP:DESTRUCTURING-BIND.  The former signals an error, while the
latter does not (it's probably very similar to the Explorer version,
since they are genetically closer).

                                                barmar

∂16-Mar-89  1726	X3J13-mailer 	Issue: MAKE-STRING-FILL-POINTER (Version 1)   
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  17:25:54 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 16:55:22 PST
Date: 16 Mar 89 16:49 PST
From: masinter.pa@Xerox.COM
Subject: Issue: MAKE-STRING-FILL-POINTER (Version 1)
to: X3J13@sail.stanford.edu
line-fold: NO
Message-ID: <890316-165522-6151@Xerox>


The  discussion on this issue pointed out that it would
extend the range of MAKE-STRING so that it was no
longer restricted to return a SIMPLE-STRING, which
might break some type-inference.

!
Issue:         MAKE-STRING-FILL-POINTER

References:    CLtL p.302

Related issues: none that I know of

Category:      ADDITION

Edit history:  Version 1, 20-Oct-88, by Moon, for discussion

Problem description:

  Once again I lost because I expected to be able to use MAKE-STRING
  to create a string with a fill-pointer, and I couldn't.  I had to use
  a more long-winded MAKE-ARRAY call instead.

Proposal (MAKE-STRING-FILL-POINTER:ALLOW):

  Give MAKE-STRING a :FILL-POINTER argument, with the same syntax and
  semantics as the :FILL-POINTER argument to MAKE-ARRAY.

Examples:

  (make-string 80 :fill-pointer 0)

Test Cases:

  See examples.

Rationale:

  I frequently expect it to be allowed and am surprised when it's not.

Current practice:

  I know of no implementations that support this.

Cost to Implementors:

  5 cents.

Cost to Users:

  none

Cost of non-adoption:

  none

Performance impact:

  none

Benefits:

  Increased language consistency.

Esthetics:

  Increased language consistency.

Discussion:

Other MAKE-ARRAY options that one might want to allow, but are
not already allowed or proposed, are :INITIAL-CONTENTS, :ADJUSTABLE,
:DISPLACED-TO, and :DISPLACED-INDEX-OFFSET.  A strong case could be
made for :ADJUSTABLE (I use an implementation where it doesn't matter,
so I don't care about that), I don't think anyone would care about the 
other three.

∂16-Mar-89  1746	X3J13-mailer 	Issue: COERCE-INCOMPLETE (Version 3)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 16 Mar 89  17:45:59 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 559088; Thu 16-Mar-89 19:18:34 EST
Date: Thu, 16 Mar 89 19:18 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: COERCE-INCOMPLETE (Version 3)
To: barmar@Think.COM
cc: masinter.pa@xerox.com, x3j13@sail.stanford.edu
In-Reply-To: <19890316230020.6.BARMAR@OCCAM.THINK.COM>
Message-ID: <890316191820.6.KMP@BOBOLINK.SCRC.Symbolics.COM>

    Date: Thu, 16 Mar 89 18:00 EST
    From: Barry Margolin <barmar@Think.COM>

    ...
    Problem with DEPRECATE: Didn't we specify that the way to convert a
    lambda expression into a function object is to use (COERCE x 'FUNCTION)?
    Or did we also define a new function that does this?

Re-read FUNCTION-TYPE. The thing Beckerle really wanted and finally
got (over my objection) was that COERCE did nothing `hard' ... What
it ended up being able to be do can be expressed by #'IDENTITY and
#'SYMBOL-FUNCTION.

 (COERCE x 'FUNCTION) ==
 (ETYPECASE X
   (SYMBOL   (SYMBOL-VALUE X))
   (FUNCTION X))

I don't really think anything more needs to be provided, even if we
DEPRECATE coerce.

∂16-Mar-89  1745	X3J13-mailer 	Issue: EXTRA-RETURN-VALUES
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 16 Mar 89  17:45:24 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA18011; Thu, 16 Mar 89 00:34:36 PST
Message-Id: <8903160834.AA18011@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
	for x3j13@sail.stanford.edu; id AA18011; Thu, 16 Mar 89 00:34:36 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 16 Mar 89 03:24
To: x3j13@sail.stanford.edu
Subject: Issue: EXTRA-RETURN-VALUES


Issue:        EXTRA-RETURN-VALUES
References:   Chapter 1, Section 1.5, Working draft of standard
Category:     Clarification
Edit history: 8-JAN-89, Version 1 by Masinter
	      3-FEB-89, Version 2 by Chapman
	      10-MAR-89, Version 3 by Chapman
 

Problem: Is it OK to return extra values from Common Lisp functions?
 
Proposal: EXTRA-RETURN-VALUES:NO

A function that is specified by the standard must return EXACTLY the number 
of return values specified by the standard.  
 
Rationale:

The reason is that
additional arguments are visible to otherwise portable programs. For
instance, (multiple-value-call #'cons (floor x y)) looks portable, but it
will try to pass the wrong number of arguments to CONS if FLOOR returns an
extra value.

Current Practice:

At least one implementation returns extra values for certain functions
not currently specified to return those values.

Adoption Cost:

Implementations and their associated documentation that now contain 
functions that return extra values will have to change.

Benefits:

Programs will potentially become more portable.

Conversion Cost:

See Adoption Cost.

Aesthetics:

None.

Discussion:

∂16-Mar-89  1801	X3J13-mailer 	SYMBOL-MACROLET-SEMANTICS, version 6
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  18:01:42 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 89 17:46:06 PST
Date: 16 Mar 89 17:44 PST
From: masinter.pa@Xerox.COM
To: x3j13@sail.stanford.edu
Subject: SYMBOL-MACROLET-SEMANTICS, version 6
line-fold: NO
Message-ID: <890316-174606-6317@Xerox>

This is a proposal to amend version 5, passed in January 1989 in Kauai.

Version 6 amends version 5 to require PSETQ to behave like PSETF,
to require MULTIPLE-VALUE-SETQ to accept symbol macros (but not
general SETF places), and to specify the interaction with the
*MACROEXPAND-HOOK* function.

We would like to have the proposal reconsidered, and
accepted as amended.

!
Issue:		SYMBOL-MACROLET-SEMANTICS
References:	SYMBOL-MACROLET (88-002R page 2-81)


Related Issues: SYMBOL-MACROLET-DECLARE
Category:	CHANGE
Edit history:	29-July-88, Version 1 by Piazza
		21-September-88, Version 2 by Piazza
		22-September-88, Version 3 by Piazza 
		22-September-88, Version 4 by Piazza
		30-Nov-88, Version 5 by Masinter
		14-Mar-89, Version 6 by Steele

Problem Description:

    The SYMBOL-MACROLET construct, introduced with CLOS in X3J13 document
    88-002R, profoundly alters the interpretation of symbols appearing as
    forms in a Common Lisp program--what previously was necessarily a variable
    might now be a symbol macro instead.  Macros which appear in the body of a
    SYMBOL-MACROLET form are currently unable to determine whether a symbol
    form is a variable or a symbol macro, and, if the latter, what the
    expansion of the symbol macro is.  Consequently, complex macros (such as
    SETF or PUSH) which depend on the form of their argument(s), are unable to
    produce their desired results in some cases, as in the following example:

	    (let ((a (make-array 5))
		  (i 0))
	      (symbol-macrolet ((place  (aref a (incf i))))
	        (push x place))
	      i)		==> 2

    In addition, it would be both natural and nice to be able to write

  (with-slots (rho theta) point
    (declare (single-float rho theta))
    ...computation...)

    as well as DECLARE within SYMBOL-MACROLET forms.

Proposal (SYMBOL-MACROLET-SEMANTICS:SPECIAL-FORM):

    Change the definition of SYMBOL-MACROLET to specify that it is a special
    form, which affects the evaluation environment for symbols.  Enhance
    MACROEXPAND and MACROEXPAND-1 so that they can expand a symbol macro.
    Modify SETF et al to use the new MACROEXPAND and MACROEXPAND-1 to examine
    even symbol subforms.  Specify that the expansion of a symbol macro IS
    subject to further macro expansion in the same lexical environment as the
    symbol macro invocation, exactly analogous to normal macros. Clarify that
    within the body of a SYMBOL-MACROLET, SETQ of a symbol defined as
    a symbol macro will be treated as if it were a SETF.

    Furthermore PSETQ of a symbol defined as a symbol macro will
    behave as if it were a PSETF, and MULTIPLE-VALUE-SETQ will behave
    as if SETQ were used on each variable to be set.

    When MACROEXPAND or MACROEXPAND-1 sees a symbol macro, it calls
    the value of *MACROEXPAND-HOOK* in the same manner as for an
    ordinary macro.  The three values given to the hook function
    in this case will be an expansion function, a form (in this case
    the symbol naming the symbol macro), and an environment.  The
    only guaranteed property of the expansion function is that when
    it is applied to the form and the environment it will return the
    correct expansion of the symbol macro.  (In particular, nothing
    it said in this specification whether the expansion is conceptually
    stored in the expansion function, the environment, or both.)

Rationale:

    The potential for interaction between macros is exactly why &environment
    arguments were originally added to macros.  Changing SYMBOL-MACROLET to be
    a special form, which communicates through the &environment arguments to
    macros with MACROEXPAND and MACROEXPAND-1, would allow PUSH and SETF
    (among others) to work with SYMBOL-MACROLET in the same way they work with
    MACROLET.

    This change cannot (reasonably) support the currently specified semantics
    that the expansion text is "outside" the scope of the symbol macro.  For
    indeed, when the symbol macro is expanded, (a copy of) the expansion is
    then within the scope of the SYMBOL-MACROLET, and should then be subject
    to further scrutiny.  The issue of "infinite expansion" of symbol macros is
    no more dangerous than that of normal macros.

Current Practice:

    Portable Common Loops provides a code-walking implementation of
    SYMBOL-MACROLET as specified in 88-002R.  Symbolics Cloe has both a
    code-walking version of a SYMBOL-MACROLET macro and compiler support for
    a SYMBOL-MACROLET special form.

Cost to Implementors:

    If SYMBOL-MACROLET is modified to be a special form, compilers and
    interpreters will have to change, as well as MACROEXPAND, MACROEXPAND-1,
    PUSH, INCF, DECF, and others.

Cost to Users:

    If SYMBOL-MACROLET is converted to a special form, code-walking programs
    will have to be modified to handle SYMBOL-MACROLET correctly.  Those same
    programs would have to be modified to handle the other special forms
    specified in CLOS, anyway.

Cost of Non-Adoption:

    SYMBOL-MACROLET will retain its confusing semantics, leading to bugs when
    it interacts with complex macros and forms which produce side-effects.

    Implementations which support ONCE-ONLY will break.  For that matter, any
    mechanism which examines code and assumes that "variables" have no side
    effects will break.

Benefits:

    SYMBOL-MACROLET-SEMANTICS:SPECIAL-FORM avoids the hairiest problems
    surrounding interaction of macros (like SETF) and side effects, and makes
    SYMBOL-MACROLET consistent with MACROLET.

Aesthetics:

    If SYMBOL-MACROLET is made to be a special form, aesthetics are improved
    by making symbol macros consistent with normal macros.

Discussion:

    A case could be made for adding a new function, SYMBOL-MACRO-FUNCTION, as
    a dual of MACRO-FUNCTION.  However, symbol macros are simpler than normal
    macros: a symbol macro is associated with a single expansion form, rather
    than an arbitrary function which computes the expansion.  For this reason,
    the augmented MACROEXPAND-1 proposed here can also fill the role of
    SYMBOL-MACRO-FUNCTION: the second value of (macroexpand-1 sym env) will be
    T if and only if sym is a symbol macro, while the first value gives the
    expansion of sym, if it has one.

    Rather than extending the existing MACROEXPAND and MACROEXPAND-1
   functions, new functions could be introduced to expand symbol macros. 
   However, there seems to be no particular reason to do this.

∂16-Mar-89  2103	X3J13-mailer 	Issue: EXIT-EXTENT, v.6   
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  21:03:05 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 21:00:49 PST
Date: 16 Mar 89 20:52 PST
From: masinter.pa@Xerox.COM
Subject: Issue: EXIT-EXTENT, v.6
to: X3J13@sail.stanford.edu
cc: masinter.pa@Xerox.COM
line-fold: NO
Message-ID: <890316-210049-6699@Xerox>

This version was distributed in hardcopy form at the
January 1989 meeting, but was tabled.

There are two proposals.

!
Issue:         EXIT-EXTENT

References:    CATCH, THROW (p 142),
               BLOCK, RETURN, RETURN-FROM,
               TAGBODY, GO, UNWIND-PROTECT,
               Dynamic extent (CLtL p.37),
               Nested dynamic extents (CLtL p.38),
               Blocks can only be exited once (CLtL p.120),
               Catch is disestablished just before the values 
               are returned (CLtL p.139).
             
Related issues: UNWIND-PROTECT-NON-LOCAL-EXIT is superseded
                by this one.

Category:      CLARIFICATION

Edit history:  ... Version 5 of UNWIND-PROTECT-NON-LOCAL-EXIT, 23-May-88 ...
               Version 1, 5-Sep-88, by Moon, for discussion
               Version 2, 1-Oct-88, by Masinter, minor edits
               Version 3, 7-Oct-88, by Moon, wording improvements
               Version 4,  7-Dec-88, by Masinter, add MEDIUM from
					UNWIND-PROTECT-NON-LOCAL-EXIT, discussion.
               Version 5, 12-Dec-88, Masinter, clarify MINIMAL allows MEDIUM
               Version 6,  8-Jan-89, Masinter, fix some bugs

Problem description:

CLtL does not specify precisely when the dynamic extent (lifetime)
of a nonlocal exit such as a CATCH, BLOCK, or TAGBODY ends. 
For example, at what point is it no longer possible to RETURN-FROM
a particular BLOCK?

An "exit" refers to a point from which control can be transferred.
For a THROW or RETURN-FROM, the "exit" is the corresponding CATCH
or BLOCK body. For a GO, the "exit" is the form within the TAGBODY
which was being executed at the time the GO is performed.

The extent of an exit is dynamic; it is not indefinite. The extent
of an exit begins when the corresponding form (CATCH, BLOCK or TAGBODY
clause) is entered.  When the extent of an exit has ended, it is no
longer legal to return from it.

The extent of an exit is not the same thing as the scope of the
designator by which the exit is identified. For example, a BLOCK
name has lexical scope but the extent of its exit is dynamic; the
scope of a CATCH tag could differ from the extent of the CATCH's
return point. (That's part of what is at issue here.)

The ambiguity at issue arises for the case where there are transfers
of control from the cleanup clauses of an UNWIND-PROTECT.

When a transfer of control is initiated by GO, RETURN-FROM or THROW,
a variety of events occur before the transfer of control is complete.
In particular, 

(a) the cleanup clauses of any intervening UNWIND-PROTECT clauses
    are evaluated,

(b) intervening dynamic bindings of special variables and catch tags
    are undone,

(c) intervening exits are "abandoned", i.e., their extent ends and it
    is no longer legal to attempt to transfer control through them,

(d) the extent of the exit being invoked ends,

(e) control is finally passed to the target.

The order of these events is not explicit in CLtL, however. The 
implementation note on p.142 gives a clue about the interweaving
of (a) and (b), but there are differing opinions about the times
at which (c) and (d) may occur. In particular,

Is it legal for an implementation to end the extent of all 
intervening exits before processing the cleanup clauses of intervening 
UNWIND-PROTECTs?

What is the dynamic context at the time UNWIND-PROTECT clauses are 
evaluated: how is the unwinding of dynamic bindings intertwined with 
evaluation of UNWIND-PROTECT cleanup clauses? 

Proposal (EXIT-EXTENT:MINIMAL):

The extent of an exit--whether it is being "abandoned" because it is 
being passed over, or it is itself the target exit--ends as soon as 
the transfer of control is initiated. That is, the events (c) and (d) 
at the beginning of the initiation of the transfer of control. In the 
language of the implementation note on p.142, the extent ends at the 
beginning of the second pass.  It is an error to attempt a transfer 
of control to an exit whose dynamic extent has ended.

Otherwise, events (a) and (b)--the undoing of dynamic binding of special
variables and CATCH tags, and the execution of UNWIND-PROTECT cleanup
clauses--are performed in the order corresponding to the reverse order
in which they were established, as implied by the implementation note
on p.142. The effect of this is that the cleanup clauses of an UNWIND-PROTECT
will see the same dynamic bindings of variables and CATCH tags as were
visible when the UNWIND-PROTECT was entered.

This proposal is called "minimal" because it gives exits the smallest
extent consistent with CLtL. A program that presumed a longer extent
would be in error. Implementations may support longer extents for
exits than is required by this proposal; in particular, an 
implementation which allowed the larger extent of the MEDIUM
proposal below would still conform.

Proposal (EXIT-EXTENT:MEDIUM):

The events of (a), (b), (c) and (d) are interwoven in the reverse 
order in which they were established. In particular, the extent of 
a passed-over exit ends when control reaches a frame that was 
established before the exit was established.  

In particular, it is legal, during the evaluation of an UNWIND-PROTECT 
cleanup form executed because of a non-local transfer of control, to
initiate a new transfer of control to an exit intervening between the 
UNWIND-PROTECT and the original target; the original processing of 
transfer of control is abandoned.  

Examples:

;; Error under either proposal: BLOCK exits normally before RETURN
(funcall (block nil #'(lambda () (return))))

;; Error under either proposal: normal exit before GO
(let ((a nil)) 
  (tagbody t (setq a #'(lambda () (go t))))
  (funcall a))

;; Error under either proposal: TAGBODY is passed over, before GO
(funcall (block nil
           (tagbody a (return #'(lambda () (go a))))))


;;returns 2 under MEDIUM, is error under MINIMAL
(block nil   
  (unwind-protect (return 1)
    (return 2)))

;;returns 2 under MEDIUM, is error under MINIMAL
(block a    
  (block b
    (unwind-protect (return-from a 1)
      (return-from b 2))))

;; returns 2 under MEDIUM, is error under MINIMAL
(catch nil 
  (unwind-protect (throw nil 1)
    (throw nil 2)))

;; returns 2 under MEDIUM, is error under MINIMAL
;; because the catch of B is passed over by
;; the first THROW, hence portable programs must assume its dynamic extent
;; is terminated.  The binding of the catch tag is not yet disestablished
;; and therefore it is the target of the second throw.
(catch 'a
  (catch 'b
    (unwind-protect (throw 'a 1)
      (throw 'b 2))))


;; the following is an error under MINIMAL; the extent of the
;; inner catch terminates as soon as the THROW commences, even
;; though it remains in scope. Thus, the THROW of :SECOND-THROW
;; sees the inner CATCH, but its extent has ended.
;; under MEDIUM, it prints "The inner catch returns :SECOND-THROW"
;; and then returns :OUTER-CATCH.
(catch 'foo
	(format t "The inner catch returns ~s.~%"
		(catch 'foo
		    (unwind-protect (throw 'foo :first-throw)
			(throw 'foo :second-throw))))
	:outer-catch))


;; Following returns 10 under either proposal.  The inner
;; CATCH of A is passed over, but because that CATCH
;; is disestablished before the THROW to A is executed,
;; it isn't seen.
(catch 'a
  (catch 'b
    (unwind-protect (1+ (catch 'a (throw 'b 1)))
      (throw 'a 10))))


;; Following is an error under MINIMAL because the extent of
;; the (CATCH 'FOO ...) exit ends when the (THROW 'FOO ...)
;; commences.
;; Under MEDIUM, the pending exit to tag FOO is discarded by the
;; second THROW to BAR and the value 4 is transferred to
;; (CATCH 'BAR ...), which returns 4. The (CATCH 'FOO ...)
;; then returns the 4 because its first argument has returned
;; normally.  XXX is not printed.

    (CATCH 'FOO
      (CATCH 'BAR
	  (UNWIND-PROTECT (THROW 'FOO 3)
	    (THROW 'BAR 4)
	    (PRINT 'XXX))))

 
;; Following returns 4 under either proposal; XXX is not printed.
;; The (THROW 'FOO ...) has no effect on the scope of the BAR
;; catch tag or the extent of the (CATCH 'BAR ...) exit.
(CATCH 'BAR
    (CATCH 'FOO
	(UNWIND-PROTECT (THROW 'FOO 3)
	  (THROW 'BAR 4)
	  (PRINT 'XXX))))


;;The following are legal and print 5 under either proposal:
    (block nil
      (let ((x 5))
        (declare (special x))
        (unwind-protect (return)
          (print x))))		

    (block nil
      (let ((x 5))
        (declare (special x))
        (unwind-protect
            (if (test) (return))
          (print x))))	


Rationale:

For MINIMAL: Giving exits the smallest extent consistent with CLtL
maximizes freedom for implementations; there are few applications,
if any, that require a longer extent.

For MEDIUM: Giving exits a longer extent has cleaner semantics.

Current practice:

Both implementations of Symbolics Genera (3600 and Ivory) end the extent
of a target BLOCK or CATCH at the moment the values are returned, and
end the extent of a passed-over exit at the moment the THROW, RETURN, or
GO commences.  This choice of extent maximizes efficiency within the
particular stack structure used by these implementations, by avoiding
the need to retain the control information needed to use a passed over
exit through the transfer of control.  Genera signals an error if an
attempt is made to use an exit that has been passed over.

In some implementations, it is possible for a throw or non-local exit
to be effectively "stopped" by an UNWIND-PROTECT cleanup clause that
performs a non-local transfer of control to a passed-over exit.

Some implementations crash or otherwise generate garbage code for
non-local exits from cleanup clauses of UNWIND-PROTECT.

Cost to Implementors:

No currently valid implementation will be made invalid by the MINIMAL
proposal. Some implementors may wish to add error checks if they
do not already have them.

MEDIUM would have a high cost for those implementations that currently
have shorter extent.

Cost to Users:

Most user programs don't do this, so there is likely little cost
of converting existing code in any case. In any case, current implementations
differ enough that this issue ostensibly does not
affect current portable programs. Some users might have code that
relies on the "unstoppable loops" that can be created with the MEDIUM
proposal.

Benefits:

Either proposal would make Common Lisp more precisely defined.

Cost of non-adoption :

The semantics of exits will remain ambiguous.

Esthetics:

Precisely specifying the meaning of dynamic extent improves the language.
Leaving implementations free to implement a longer extent if they choose
can be regarded as unesthetic, but consistent with Common Lisp philosophy.
Having a CATCH that is in scope even though its extent has ended may
seem unesthetic, but it is consistent with how BLOCK behaves.

Discussion:

This issue is controversial. It was first discussed under the issue 
named UNWIND-PROTECT-CLEANUP-NON-LOCAL-EXIT. The issue was recast as
the more global one of "extent of exits" rather than the specific 
one of "what happens if a cleanup in an UNWIND-PROTECT does a non-
local exit", but the problem cases for both topics are the same.

The goal of the MINIMAL proposal is to clarify the ambiguity in CLtL while
minimizing changes to the current situation. The MEDIUM proposal
defines the extent of an exit to end at the last moment possible
within some particular reference implementation.  It has
a cost to implementors whose implementation is not identical to the
reference implementation.  Another alternative proposal, not considered
here, would duck the issue by outlawing all non-local exits from UNWIND-PROTECT
cleanup forms. That alternative would have a substantial cost to some users.

Scheme is cleaner: it avoids this issue by specifying that the extent
of an exit never ends.

An argument for the MEDIUM proposal was made based on the example:

  (block foo
    (block bar
      (unwind-protect
          (return-from foo 'foo)
	(return-from bar 'bar))))

Since there is no reason for FOO and BAR not to be treated interchangeably,
calling this an error would be inappropriate. 

It was argued that the MINIMAL proposal is equivalent to practically
outlawing non-local exits from UNWIND-PROTECT cleanup clauses, because
there is no general way to determine the target of the non-local exit
that caused the cleanup clause to be invoked. 

The following example was offered as an argument against MINIMAL. Given:

    (block nil
      (handler-case
          (unwind-protect (return)
            (error "foo"))             ;probably an error, under the proposal
        (error ()
          (print "foo"))))

If the ERROR handler has the same scope and extent a CATCH in the same place
would have (and that seems reasonable, though I'm not certain that the
condition system specifically requires that interpretation), then the handler
will be apparent to the call to ERROR, but will no longer be a valid target
(its extent was exited by the RETURN in the UNWIND-PROTECT body).

The extent of an object with dynamic extent is the extent of the form 
which created it.  Code which is executed "within" that form is within
the extent of the object(s).  This applies to all dynamic objects, such
as special variable bindings, not just exits.  Actually, I think the intent
of the implementation note on p.142 is fairly clear and supports this
interpretation.  The supposedly ambiguous use of "frame" should be read
as something like "form which establishes a dynamic extent".  It might be
clearer if the last sentence were changed to read something like:

"On the second pass the stack is actually unwound.  Each form which establishes
a dynamic extent is undone in reverse order of creation until the matching
CATCH is reached.  The meaning of undoing a form depends on the type of form.
For UNWIND-PROTECT, it means executing the cleanup forms.  For CATCH it means
removing the CATCH tag.  For dynamic bindings it means undoing the binding,
restoring the previous saved value. {This is not an exhaustive listing of the
possibilities.}"



     ----- End Forwarded Messages -----

∂16-Mar-89  2220	X3J13-mailer 	Issue: FUNCTION-COERCE-TIME (Version 2)  
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  22:20:17 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 22:18:04 PST
Date: 16 Mar 89 22:17 PST
Sender: masinter.pa@Xerox.COM
Subject: Issue: FUNCTION-COERCE-TIME (Version 2)
From: cl-cleanup@sail.stanford.edu
To: x3j13@sail.stanford.edu
REPLY-TO: cl-cleanup@sail.stanford.edu
cc: Masinter.pa@Xerox.COM
Message-ID: <890316-221804-6820@Xerox>

Unfortunately, there have been no new versions of this
produced since it was last distributed, labelled DRAFT, to X3J13
prior to the October, 1988 meeting in Fairfax.

Excerpts from the mail on this are appended.
!
Issue:        FUNCTION-COERCE-TIME
References:   SET-MACRO-CHARACTER (p362),
	      SET-DISPATCH-MACRO-CHARACTER (p364),
	      MAP (p249), MAPL (p129), ...
	      Functions using :TEST, :KEY, etc. (REDUCE, MEMBER, DELETE, ...)
	      Functions using a positional predicate (SORT, DELETE-IF, ...)
Category:     CLARIFICATION
Edit history: 20-Jun-88, Version 1 by Pitman
	      16-Sep-88, Version 2 by Pitman
	       (changes to presentation of all proposals per Masinter's comments)
Status:	      For Internal Discussion

Problem Description:

  Many functions which accept arguments which are to be treated functionally
  but which are not of type FUNCTION. This functionality can be very useful,
  but the time at which the coercion is accomplished must be made clear.

Proposal (FUNCTION-COERCE-TIME:LAZY):

  Specify that when a non-function (eg, a symbol) is used as a functional
  argument to an operator, the coercion of that non-function to a function
  is delayed until the function is about to be called and is done anew
  every time the function is to be called. That is, passing a non-function
  functional argument, F, is equivalent to passing
   #'(LAMBDA (&REST ARGUMENTS)
       (APPLY F ARGUMENTS))

  Rationale:

    One of the main reasons that it may be useful to pass a non-function
    instead of a function is to accomplish indirection which allows later
    redefinitions to take proper effect. Early binding would tend to
    thwart the usefulness of such indirection and force people into
    notationally more clumsy devices.

Proposal (FUNCTION-COERCE-TIME:AMBITIOUS):

  Specify that when a non-function (eg, a symbol) is used as a functional
  argument to an operator, the coercion of that non-function to a function
  is done immediately. That is, all such functions treat a non-function
  functional argument, F, as if
   (COERCE F 'FUNCTION)
  had been passed instead.

  Rationale:

    This is easier to implement since the coercion is done up front and
    no further worry about uncoerced functions is needed internally.

    Also, inlining of mapped functions (without using temporary storage
    to hold a cached value of the function being mapped) can be done
    without needing to know whether the function being inlined will
    affect the place which holds the functional argument being passed.

Proposal (FUNCTION-COERCE-TIME:HYBRID):

  Specify that when a non-function (eg, a symbol) is used as a 
  functional argument to an operator, the coercion of that non-function
  to a function must be done immediately if the functional argument is
  to be used only internally to the function (eg, SORT or MAPCAR).
  Otherwise, if the functional argument's use persists beyond the end
  of the call to the operator (eg, SET-MACRO-CHARACTER), any coercion is
  delayed until the function is about to be called and is done anew every
  time the function is to be called.

  That is, functions like SORT and MAPCAR are permitted to treat a 
  non-function functional argument, F, as if
   (COERCE F 'FUNCTION)
  had been passed instead. However, functions like SET-MACRO-CHARACTER
  would treat a non-function functional argument, F, as if
   #'(LAMBDA (&REST ARGUMENTS)
       (APPLY F ARGUMENTS))
  were passed instead.

  Rationale:

    Debugging is enhanced for operations such as SET-MACRO-CHARACTER
    without needlessly hampering useful optimizations to things like
    SORT or MAPCAR, which very rarely require this facility.

Test Cases:

  (DEFVAR *SOME-FUNCTIONS*
	  (LIST #'(LAMBDA (X) (SETF (SYMBOL-FUNCTION 'FOO) X) 1)
		#'(LAMBDA (X) (SETF (SYMBOL-FUNCTION 'FOO) X) 2)
		#'(LAMBDA (X) (SETF (SYMBOL-FUNCTION 'FOO) X) 3)
		#'(LAMBDA (X) (SETF (SYMBOL-FUNCTION 'FOO) X) 4)))

  ; Control situation A
  (PROGN (SETF (SYMBOL-FUNCTION 'FOO) (CAR *SOME-FUNCTIONS*))
	 (LIST (MAPCAR #'(LAMBDA (&REST X) (APPLY #'FOO X))
		       *SOME-FUNCTIONS*)
	       (FOO T)))
  => ((1 1 2 3) 4)

  ; Control situation B
  (LET ((FOO (SETF (SYMBOL-FUNCTION 'FOO) (CAR *SOME-FUNCTIONS*))))
    (LIST (MAPCAR FOO
		  *SOME-FUNCTIONS*)
		  (FOO T)))
  => ((1 1 1 1) 4)

  ; Interesting Situation 1
  (PROGN (SETF (SYMBOL-FUNCTION 'FOO) (CAR *SOME-FUNCTIONS*))
	 (LIST (MAPCAR #'FOO
		       *SOME-FUNCTIONS*)
	       (FOO T)))
  =>    ((1 1 2 3) 4)				;Lazy-1
     or ((1 1 1 1) 4)				;Ambitious-1


  ; Interesting Situation 2
  (PROGN (SETF (SYMBOL-FUNCTION 'FOO) (CAR *SOME-FUNCTIONS*))
	 (LIST (MAPCAR 'FOO
		       *SOME-FUNCTIONS*)
	       (FOO T)))
  =>    ((1 1 2 3) 4)				;Lazy-2
     or ((1 1 1 1) 4)				;Ambitious-2

  (DEFUN SHARP-DOLLAR (STREAM CHAR N)
    (DECLARE (IGNORE CHAR))
    (EXPT (READ STREAM) (OR N 1)))

  (SET-DISPATCH-MACRO-CHARACTER #\# #\$ 'SHARP-DOLLAR)

  (VALUES (READ-FROM-STRING "(#$3 #4$3)"))
  => (3 81)

  (DEFUN SHARP-DOLLAR (STREAM CHAR N)
    (DECLARE (IGNORE CHAR))
    (+ (READ STREAM) (* (OR N 0) 0.01))) 

  (VALUES (READ-FROM-STRING "(#$3 #4$3)"))
  => (3.0 3.04)					;Lazy-3
     (3 81)					;Ambitious-3

  Proposal LAZY      requires LAZY-1,      LAZY-2,      LAZY-3.
  Proposal AMBITIOUS requires AMBITIOUS-1, AMBITIOUS-2, AMBITIOUS-3.
  Proposal HYBRID    requires AMBITIOUS-1, AMBITIOUS-2, LAZY-3.

Current Practice:

  Implementations are permitted to differ in when they do the coercion since
  the coercion time is not clearly spelled out.

  (In the test case, LAZY-1 can occur only if MAPCAR is inlined, and then
  only if the original value of the function definition is not cached.)

  [Some info below is based on empirical testing -- I didn't look at the
   source or try to see how speed/safety affect things. -kmp]

  Symbolics Genera implements AMBITIOUS-1 interpreted and LAZY-1 compiled.
  Symbolics Cloe (a compiled-only lisp) implements LAZY-1 both `interpreted'
   and compiled.

  Both Symbolics Genera and Symbolics Cloe implement LAZY-2.

  Symbolics Genera implements LAZY-3.
  Symbolics Cloe implements AMBITIOUS-3.

Cost to Implementors:

  [Costs may vary widely depending on current practice.
   I'll leave this one open for now pending feedback from others. -kmp]

Cost to Users:

  This change is upward compatible.

Cost of Non-Adoption:

  A very important aspect of the language would be left unspecified.
  Portability would suffer.

Benefits:

  HYBRID has the benefit of making things like readmacros easier to debug.

  LAZY offers the additional benefit of being able to repair certain
  functional arguments to SORT or MAPCAR (eg, as a symbol) in the debugger,
  and then to proceed the error (in implementations offering that restart
  option) in a way that makes the ongoing call to SORT or MAPCAR notice
  the repairwork right away.

Aesthetics:

  Since this is a visible aspect of the language, anything which clarified
  the behavior that a programmer might expect would seem to improve the
  aesthetics somewhat.

Discussion:

  This issue was raised by Nick Gall and written up by Pitman.
  Pitman supports FUNCTION-COERCE-TIME:HYBRID.

!
Additional comments:

There was some concern about the proposal wording, because
it was trying to allow for the possibility that implementations
might extend other objects (e.g., lists that begin with
LAMBDA) to "coerce" to functions, and the proposal should
apply for them, too.

This made the wording of the proposal pretty awkward, though.
- - - - - -
The writeup for the LAZY option should mention that this might cause a
substantial performance hit in some implementations.

Of the options presented, I prefer AMBITIOUS.  However, I would really
much rather see this whole issue left explicitly vague in the
standard.  
- - - - 
notes from Cleanup meeting (Fairfax, 1988):

 Eliminate the AMBITIOUS proposal. Continue to evolve the
	   HYBRID and LAZY variants.

 Relation to DEBUG quality.

 There was some discussion about the idea of permitting vagueness
 (ie, making LAZY/AMBITIOUS optional in some places).

X3J13 meeting:

 Some people weren't completely convinced that the HYBRID proposal
 would feel predictable enough. Others disagreed.
- - - - - - - -
Well, the main reason why I prefer "AMBITIOUS" to "HYBRID" is that it
seems kind of peculiar to make an exception for the two functions,
SET-MACRO-CHARACTER and SET-DISPATCH-MACRO-CHARACTER.  Besides being
different from all the other functions that take functional arguments,
it makes them different from the pathname functions (which always
coerce non-pathname "pathname" arguments to pathnames) and the package
functions (which always coerce non-package "package" arguments to
packages). 

Also, I disagree that there is no performance penalty, although it's
certainly small in comparison to the rest of the reader's processing.
For example, A-Lisp has a fast, opencoded funcall primitive that it
uses when its argument is guaranteed to be a function, which is *much*
faster than a normal funcall (by a factor of at least 20).

I don't feel really strongly about this -- HYBRID is not really all
that objectionable to me, and I would vote for it if AMBITIOUS is
thrown out. 
-------
... I'm thinking of a revision  which might lean more toward
explicitly vague on some of these issues. At the same time,
I'd like to encourage the use of the DEBUG and/or SPEED quality
to help compilers lean toward LAZY in the slow/easy-to-debug
case and AMBITIOUS in the fast/hard-to-debug case. There are
some details to be worked out, though...

∂16-Mar-89  2254	X3J13-mailer 	Issue: HASH-TABLE-ACCESS (version 2)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  22:53:48 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 22:51:36 PST
Date: 16 Mar 89 22:51 PST
From: masinter.pa@Xerox.COM
Subject: Issue: HASH-TABLE-ACCESS (version 2)
to: X3J13@sail.stanford.edu
Line-fold: NO
Message-ID: <890316-225136-6875@Xerox>

Version 1 of this issue was distributed prior
to the October 1988 meeting.

This version was produced in response to
comments there.

Additional comments are at the end.
!
Issue: HASH-TABLE-ACCESS
References:	hash-tables (Chapter 21 of CLtL)
Category:	ADDITION
Edit History: 13-Sept-88, version 1 by Walter van Roggen
              13-Oct-88, version 2 by Walter van Roggen
 
Problem Description:
 
  There are many characteristics of hash-tables which are specified upon
  creation but are not accessible afterwards.
 
Proposal: (HASH-TABLE-ACCESS:PROVIDE)
 
  Add the following functions to the language:
 
  HASH-TABLE-REHASH-SIZE hash-table
 
    Returns the current rehash size of a hash table.
 
  HASH-TABLE-REHASH-THRESHOLD hash-table
 
    Returns the current rehash threshold of a hash table.
 
  HASH-TABLE-SIZE hash-table
 
    Returns the current size of a hash table.
 
  HASH-TABLE-TEST hash-table
 
    Returns the test used for comparing keys in the hash table.
    By default the value will be EQL.
 
 
Current Practice:
 
  VAX LISP and Lucid 3.0 implement the proposal.
 
Cost to Implementors:
 
  Most of these should be trivial to implement, since the information
  must be present for nearly all types.
 
Cost to Users:
 
  None.  This is an upward-compatible extension.
 
Cost of Non-Adoption:
 
  The benefits would not be available in a portable fashion.
 
Benefits:
 
  Programs would be able to access useful information otherwise hidden.
  For example, it would allow programs to gain statistics about hash
  table usage that might enable better tuning.
 
Discussion:
 
  None of these are required to be SETF'able, though some might be
  reasonable implementation-dependent extensions.  Including such
  modification abilities might constrain some implementations unduly.
 
  This first appeared in ">GLS>clarifications.text" of 12/06/85.
!
Additional Comments:

Adding accessors for hash tables seems like a reasonable idea to me,
but I don't like the idea of being able to SETF them.

- - - - -
     HASH-TABLE-REHASH-SIZE hash-table
       Returns the current rehash size of a hash table.
     HASH-TABLE-REHASH-THRESHOLD hash-table
       Returns the current rehash threshold of a hash table.
     HASH-TABLE-SIZE hash-table
       Returns the current size of a hash table.

I don't think the "current" values of these are well defined except in
reference to one particular implementation technique (I believe the
corresponding arguments to make-hash-table are advisory in nature and can be
ignored when not applicable).  For instance, can you describe what an
implementation using alists should return from each of these functions?

I do support the addition of HASH-TABLE-TEST.

- - - - - - -
Well, I think there would be some leeway on the return values for
HASH-TABLE-REHASH-SIZE/REHASH-THRESHOLD/SIZE too.

If an implementation really did implement them with association lists,
perhaps reasonable return values would be:
  HASH-TABLE-REHASH-SIZE  1
  HASH-TABLE-REHASH-THRESHOLD  1.0
  HASH-TABLE-SIZE  the length of the association list

- - - - - - -
I still would like to see SETF enabled for:

    HASH-TABLE-REHASH-SIZE
    HASH-TABLE-REHASH-THRESHOLD

At issue is the rate of "rehashing" between successive, novel entries
into the table, and the rate of consing to maintain the table.  [Perhaps 
this would be clearer if there were a function in the language called 
REHASH; Lucid 3.0 has such a function, and Interlisp-D had such a function.]

Of course, the setf methods for these two accessors would do a good deal of 
argument and consistency checking.  So what possible harm could come from 
permitting the user to alter these parameters after initial creation?  those 
implementations that substitute alists for "hash-tables" can try to adapt to 
this view, that some kind of "rehash" step [with some determined cost] is 
done after the entry which first makes:

    (hash-table-count x)  >  (* (hash-table-size x)
                                (hash-table-rehash-threshold x))

be true [assuming a floating-point value for the threshold].  This is part 
of the whole point for having "hash tables" in the language.

- - - - -
I'm quite sympathetic to being able to SETF some of the hash-table readers,
but I didn't think it appropriate to require of all implementations.

- - - - - -
The value of HASH-TAbLE-REHASH-SIZE and HASH-TAbLE-REHASH-THRESHOLD are
implementation dependent, and guaranteed to be greater than or equal to the
values given to MAKE-HASH-TABLE, and idempotent, in that if you make a hash
table with the same values as a given hash table then the -REHASH-SIZE and
-REHASH-THRESHOLD of the newly created one will be the same as the input
values. (This says that they may be thresholded upward in some
implementation-dependent-manner.)

HASH-TABLE-SIZE should be greater than or equal to the count of things
MAPHASH would iterate over, and HASH-TABLE-TEST will return one of the
symbols EQ EQL EQUAL (or, if HASH-TABLE-TESTS passes, EQUALP), even if #'EQ
#'EQUAL #'EQL are given.

Normally implementation-dependent-extensions are explicitly discouraged;
I'm no longer sure at the momemnt whether PACKAGE-CLUTTER would explicilty
disallow such extensions unless they are explicitly allowed, but we should
be cautious in throwing around phrases like "might be
  reasonable implementation-dependent extensions" if we don't mean it. I
would take that out, actually.

∂16-Mar-89  2244	X3J13-mailer 	Issue: SETF-FUNCTION-VS-MACRO, SETF-PLACES, FUNCTION-NAME, v.1    
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  22:43:21 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 22:40:08 PST
Date: 16 Mar 89 22:34 PST
From: masinter.pa@Xerox.COM
Subject: Issue: SETF-FUNCTION-VS-MACRO, SETF-PLACES, FUNCTION-NAME, v.1
To: X3J13@sail.stanford.edu
line-fold: NO
Message-ID: <890316-224008-6866@Xerox>


This issue has been renamed several times; however, it is
the same old issue. I say this lest anyone think we can
'two week' it away.

We didn't have a 'letter ballot' and so we have to talk
about it. Maybe.

Additional Comments are at the end; including a fairly substantial
additional proposal.
!
Issue:         FUNCTION-NAME

References:    SETF rules for what -place- can be (pp.94-7)
               FBOUNDP function (p.90)
               FMAKUNBOUND function (p.92)
               FUNCTION special form (p.87)
               SYMBOL-FUNCTION and setf of symbol-function (p.90)
               88-002R pages 1-21, 2-21, 2-26, 2-39, 2-44, 2-46, 2-51, and 2-55
               (There are additional references for the MEDIUM and LARGE
                proposals, but they are not listed here.  They're obvious.)

Related issues: SETF-FUNCTION-VS-MACRO, SETF-PLACES (both subsumed by this)

Category:      ADDITION

Edit history:  Version 1, 23-Jan-89, by Moon 
                              (based on discussion at X3J13 meeting)


Problem description:

The Common Lisp Object System needs a well-defined way to relate the name
and arguments of a writer function to those of a reader function, because
both functions can be generic and can have user-defined methods.  The way
that was adopted into Common Lisp when X3J13 voted to accept document
88-002R was to use a list (SETF reader) as the name of the writer function.

Some changes to the non-object-oriented portion of Common Lisp are required
in order to support this.

This issue has three proposals.


Proposal (FUNCTION-NAME:SMALL):
          
  Add a new concept "function-name" (called "function-specifier" in
  88-002R).  A function-name is either a symbol or a 2-element list whose
  first element is the symbol SETF and whose second element is a symbol.
  Implementations are free to extend the syntax of function-names to
  include lists beginning with additional symbols other than SETF.

  Add a new function (FDEFINITION function-name), which returns the
  current global function definition named by function-name, or signals
  an error if there is no global function definition.  This follows all
  the same rules listed for SYMBOL-FUNCTION in CLtL p.90.

  Add SETF of FDEFINITION to change the current global function definition
  named by a function-name.  This follows all the same rules listed for
  SETF of SYMBOL-FUNCTION in CLtL p.90.

  Change the FBOUNDP and FMAKUNBOUND functions, and the FUNCTION special
  form, to accept function-names in place of symbols.  Implementation
  defined extensions to the syntax of function-names cannot use the
  symbol LAMBDA, since FUNCTION already uses that symbol.

  Change the rules for SETF places (CLtL pp.94-7) by adding the following
  clause after all the existing clauses:

   - Any other list whose first element is a symbol, call it reader.
     In this case, SETF expands into a call to the function named by the
     list (SETF reader).  The first argument is the new value and the
     remaining arguments are the values of the remaining elements of
     -place-.  This expansion occurs regardless of whether reader or
     (SETF reader) is defined as a function locally, globally, or not at
     all.  For example,
         (SETF (reader arg1 arg2...) new-value)
     expands into a form with the same effect and value as
         (LET ((#:temp-1 arg1)          ;force correct order of evaluation
               (#:temp-2 arg2)
               ...
               (#:temp-0 new-value))
           (FUNCALL (FUNCTION (SETF reader)) #:temp-0 #:temp-1 #:temp-2...)).

  Change the functions GET-SETF-METHOD and GET-SETF-METHOD-MULTIPLE-VALUE
  to implement the above change to the rules.
         
  Document that a function named (SETF reader) should return its first
  argument as its only value, in order to preserve the semantics of SETF.

  Change the macro DEFGENERIC and the function ENSURE-GENERIC-FUNCTION to
  refer to the function FDEFINITION where they now refer to the function
  SYMBOL-FUNCTION.

  Change the macros DEFCLASS, DEFGENERIC, and DEFMETHOD, the special forms
  GENERIC-FLET and GENERIC-LABELS, and the functions DOCUMENTATION and
  ENSURE-GENERIC-FUNCTION to use the term "function-name" where they now
  use the term "function-specifier" or "function specifier".


Rationale for FUNCTION-NAME:SMALL:

  This is the minimum change to Common Lisp needed to do what 88-002R says
  about (SETF reader).  Giving implementations freedom to extend the syntax
  of function-names allows for current practice.  Changing the name from
  "function-specifier" to "function-name" avoids confusion and improves
  consistency with the rest of the language, at the cost of a few small
  changes to 88-002R.


Proposal (FUNCTION-NAME:MEDIUM):

  Everything in FUNCTION-NAME:SMALL, and in addition:

  Change the DEFUN macro to accept a function-name for its name argument,
  instead of only accepting a symbol.  If function-name is (SETF sym),
  the body is surrounded by an implicit block named sym.


Rationale for FUNCTION-NAME:MEDIUM:

  Keeping DEFUN consistent with DEFMETHOD is a good idea.  Also 88-002R
  says "The name of a generic function, like the name of an ordinary
  function, can be either a symbol or a two-element list whose...", which
  implies this change to DEFUN.


Proposal (FUNCTION-NAME:LARGE):

  Everything in FUNCTION-NAME:MEDIUM, and in addition the following
  numbered points, each of which could be adopted independently,
  except where explicitly noted:

  1. Change the function COMPILE to accept a function-name as its name
  argument.

  2. Change the function DISASSEMBLE to accept a function-name as its name
  argument.

  3. Change the FTYPE, INLINE, and NOTINLINE declarations and proclamations
  to accept function-names, not just symbols, as function names.

  4. Change the FLET and LABELS special forms to accept a function-name in
  the name position, not just a symbol.

  5. Change the TRACE and UNTRACE macros to accept function-names, not just
  symbols, in the function name positions.

  6. Change the ED function to accept (ED function-name) in place of
  (ED symbol).

  7. Change the syntax of a function call to allow a function-name as the
  first element of the list, rather than allowing only a symbol.

  8. Change the DEFMACRO macro and the MACROLET special form to accept a
  function-name in the name position, not just a symbol.  Change the
  MACRO-FUNCTION function to accept function-names, not just symbols.
  Change the last rule for SETF places to use
    ((SETF reader) #:temp-0 #:temp-1 #:temp-2...)
  in place of
    (FUNCALL (FUNCTION (SETF reader)) #:temp-0 #:temp-1 #:temp-2...)
  so that (SETF reader) can be defined as a macro.  This depends on item
  7.  If item 4 is rejected, MACROLET should be stricken from this item.

  9. Add an optional environment argument to FDEFINITION, SETF of
  FDEFINITION, FBOUNDP, and FMAKUNBOUND.  This is the same as the
  &environment argument to a macroexpander.  This argument can be used to
  access local function definitions, to access function definitions in the
  compile-time remote environment, and to modify function definitions in
  the compile-time remote environment.

  10. Change the second, third, fourth, fifth, seventh, and ninth rules for
  SETF places so that they only apply when the function-name refers to the
  global function definition, rather than a locally defined function or
  macro.  (The ninth rule is the one that refers to DEFSETF and
  DEFINE-SETF-METHOD; the other rules listed are the ones that list
  specific built-in functions).  The effect of this change is that SETF
  methods defined for global functions are ignored when there is a local
  function binding; instead, the function named (SETF reader), which may
  have a local function binding, is called.  This change is most useful
  in connection with item 4, but does not actually depend on it.

  11. Clarify that the eighth rule for SETF places (the one for macros)
  uses MACROEXPAND-1, not MACROEXPAND.

Rationale for FUNCTION-NAME:LARGE:

  This extends the new feature throughout the language, in order to make
  things generally more consistent and powerful.  Point by point:

  1,2,3 - one should be able to compile, examine, and make declarations
  about functions regardless of whether they are named with symbols or
  with lists.

  4 - locally defined non-generic SETF functions are a logical companion
  to locally defined generic SETF functions, which can be defined with
  GENERIC-FLET or GENERIC-LABELS.  They make sense on their own, since one
  might define a local reader function and want a local writer function
  to go with it.

  5,6 - one should be able to apply development tools to functions
  regardless of how they are named.  The function DOCUMENTATION was already
  updated to work for function-names by 88-002R.  There might be some
  difficulty with implementation-dependent syntax extensions to TRACE and
  UNTRACE conflicting with this new syntax.

  7 - this restores consistency between the FUNCTION special form and the
  first element of a function call form.

  8 - it seems more consistent to allow macros to be named the same way
  that ordinary functions are named.  However, this might be considered
  redundant with DEFSETF.

  9 - this is not needed by the "chapter 1 and 2" level of CLOS, but might
  be used by the metaobject based implementation of ENSURE-GENERIC-FUNCTION.

  10 - this change was in SETF-FUNCTION-VS-MACRO and makes item 4 more useful.

  11 - this change was in SETF-FUNCTION-VS-MACRO and is a good idea, but
  actually is independent of everything else being proposed here.


Examples:

;This is an example of the sort of syntax 88-002R allows
(defmethod (setf child) (new-value (parent some-class))
  (setf (slot-value 'child parent) new-value)
  (update-dependencies parent)
  new-value)
(setf (child foo) bar)

;If SETF of SUBSEQ was not already built into Common Lisp,
;it could have been defined like this, if the MEDIUM or LARGE
;proposal is adopted.
(defun (setf subseq) (new-value sequence start &optional end)
  (unless end (setq end (length sequence)))
  (setq end (min end (+ start (length new-value))))
  (do ((i start (1+ i))
       (j 0 (1+ j)))
      ((= i end) new-value)
    (setf (elt sequence i) (elt new-value j))))

;The preceding example would have to be defined like this
;if only the SMALL proposal is adopted.  This is a method
;all of whose parameter specializer names are T.
(defmethod (setf subseq) (new-value sequence start &optional end)
  (unless end (setq end (length sequence)))
  (setq end (min end (+ start (length new-value))))
  (do ((i start (1+ i))
       (j 0 (1+ j)))
      ((= i end) new-value)
    (setf (elt sequence i) (elt new-value j))))

;Another example, showing a locally defined setf function
(defun frobulate (mumble)
  (let ((table (mumble-table mumble)))
    (flet ((foo (x)
             (gethash x table))
           ((setf foo) (new x)
             (setf (gethash x table) new)))
      ..
      (foo a)
      ..
      (setf (foo a) b))))

;get-setf-method could implement setf functions by calling
;this function when the earlier rules do not apply
(defun get-setf-method-for-setf-function (form)
  (let ((new-value (gensym))
	(temp-vars (do ((a (cdr form) (cdr a))
			(v nil (cons (gensym) v)))
		       ((null a) v))))
    (values temp-vars
	    (cdr form)
	    (list new-value)
	    `(funcall #'(setf ,(car form)) ,new-value ,@temp-vars)
	    `(,(car form) ,@temp-vars))))


Current practice:

  No implementation supports exactly what is proposed.  Symbolics Genera
  and the TI Explorer support something close to the MEDIUM proposal, but
  differing in a number of details.  Symbolics Genera supports items 1, 2,
  3, 6, and 11, and modified forms of items 5 and 8, of the LARGE proposal.
  Moon considers this proposal's variations from Symbolics current practice
  to be an improvement, although incompatible in some cases.
  
  Many implementations currently support only symbols as function names.

  Symbolics Genera and the TI Explorer have some additional function-name
  syntaxes.

Cost to Implementors:

  The SMALL and MEDIUM proposals are estimated to be no more than 50 lines
  of code and require no changes to the "guts" of the interpreter and
  compiler.  Most of the code for this can be written portably and was
  shown on two slides at the X3J13 meeting.

  Some of the changes in the LARGE proposal are trivial, some require
  the compiler to use EQUAL instead of EQ to compare function names, and
  items 4, 7, and 8 might require a more substantial implementation
  effort.  Even that effort is estimated to be negligible compared to
  the effort required to implement CLOS.

Cost to Users:

  No cost to users, other than program-understanding programs, since this
  is an upward compatible addition.

  As with any language extension, some program-understanding programs may
  need to be enhanced.  A particular issue here is programs that assume
  that all function names are symbols.  They may use GET to access
  properties of a function name or use EQ or EQL (perhaps via MEMBER or
  ASSOC) to compare function names for equality.  Such programs will need
  improvement before they can understand programs that use the new feature,
  but otherwise they will still work.

Cost of non-adoption:

  We would have to make some other language change since the language
  became inconsistent when 88-002R was adopted.

Performance impact:

  This has no effect on performance of compiled code.  It might slow
  down the compiler and interpreter but not by very much.

Benefits:

  CLOS will work as designed.

Esthetics:

  Some people dislike using anything but symbols to name functions.
  Other people would prefer that if the change is to be made at all,
  the LARGE proposal be adopted so that the language is uniform in its
  treatment of the new extended function names.  Other proposals for
  how to deal with SETF in CLOS were considerably less esthetic,
  especially when package problems are taken into account.
  
  SETF would be more esthetic, but less powerful, if it had only the
  proposed setf functions and did not have setf macros.  Such a major
  incompatible change is of course out of the question; however, if setf
  functions are stressed over setf macros, SETF will be much easier to
  teach.

Discussion:

  Moon supports at least FUNCTION-NAME:MEDIUM.  He does not necessarily
  approve of all parts of FUNCTION-NAME:LARGE.


!
Additional Comments:

On the whole, I like this presentation much better than either of the
other two writeups that were circulated previously.  I suspect that it
might be necessary to vote on each of the items in the LARGE proposal
individually, though.  I think I would support items 1, 2, and 11, and
don't have any particular objections to 3, 5, and 6.  For item 4, if
consistency with GENERIC-FLET and GENERIC-LABELS is an object, another
alternative is to change those two special forms to be like ordinary
FLET and LABELS, instead of vice versa.

- - - - - - -
I support FUNCTION-NAME:MEDIUM and may support LARGE once I think about
it some more.

As I explained in Hawaii, support for either of these is based on the
:conc-name bugs being removed from the condition system.  Of course, I
believe the best way to do that is to CLOSify it.
- - - - - - - - 
I'm still thinking about this, but while I am I wanted point out that
MEDIUM is unacceptable to me because I don't think FLET and DEFUN should
disagree on what they permit as defined names. If FLET were added to
MEDIUM, I suspect I'd think it was an internally consistent position.

LARGE has an appeal to me in general, but I'm still mulling over 
the specifics.
- - - - - - - - - -
I favor the FUNCTION-NAME:LARGE proposal, because it defines a single,
useful notion of what a function name is.  The other proposals have
the flaw that there are two kinds of function names:  symbols, and
extended names, with only some of the Lisp primitives accepting the
latter.  This may be convenient for some implementations, for the
short term, but it fragments the language.

I have two other comments on the proposal.


A. Reducing the Cost to Implementors

One observation you could put in the Cost To Implementors section is
that none of the SMALL, MEDIUM, or LARGE proposals require changes to
the "guts" of the interpreter and compiler.  This is because an
implementation is free to use plain symbols internally to name
functions, and use a hack like JonL's SETF:|3.FOO.BAR| mapping to
convert non-symbol names to symbols.  This conversion would be done as a
part of parsing the handful of forms which accept function names, and
then all other passes of the interpreter and compiler (the "guts") would
just see symbols.  (By "parsing" I mean ensuring the right number and
type of syntactic subforms.  You can see that this is a very early and
simple stage of processing.)  Or, Lisp compilers with an "alphatization"
phase could perform function name symbolization at that phase.


B. Finishing the Job of Regularization

I'd like to suggest two additions to your smorgasbord of options in the
FUNCTION-NAME:LARGE section of the proposal.  One addition would
regularize a major special case of functions--lambda expressions.  The
other addition would reaffirm an unstated regularity in the language,
that function names can stand in for functions under FUNCALL and APPLY.
Not only can the treatment of symbolic and setf-list function names be
regularized, but lambda too can be treated in a consistent manner.

If these two points are added to your proposal, the language as a whole
would have a completely uniform treatment of functions and function
names.  Here they are:

13. Declare that any function name is a suitable argument to FUNCALL and
    APPLY.  In such a case, the function name is passed to FDEFINITION,
    and the result (which may in turn be a function name) is called.
    That is, the following two expressions are equivalent, when fname
    is a function name:
	(FUNCALL fname x y)
	  <==>
	(FUNCALL (FDEFINITION fname) x y)
    Note that the definition is sought in the global environment.
    Compare with the rule which applies to a function name occurs,
    syntactically, as the car of a list in code:
	(fname x y)
	  <==>
	(FUNCALL (FUNCTION fname) x y)
	  <==> (under proposal item 9)
	(FUNCALL (FDEFINITION fname <local-environment>) x y)

12. Declare that any lamba expression (i.e., a list whose car is LAMBDA and
    whose cdr is a well-formed lambda argument list and body) is a function
    name.  The effects of the function name accessors on lambda expressions
    are as follows.  FDEFINITION returns an implementation-defined value which
    is the function specified the lambda expression, closed in the global
    environment.  This FDEFINITION value cannot be changed by SETF.
    FBOUNDP always returns T, and MAKUNBOUND is an error.

Esthetics:

The effect of items 11 and 12 is to complete the regularization of
Common Lisp's treatment of functions and function names.  The total
effect of proposal items 1 through 12 is that Lisp has just two notions
for referencing function objects: FUNCTIONS, which are Lisp objects that
directly represent executable code, and FUNCTION NAMES, which can denote
functions.  Symbols, SETF function names, and lambda expressions are all
examples of the latter notion.  The former notion is highly
implementation dependent.  Function names can occur as syntactic
entities in code.  FUNCALL and APPLY work uniformly on both functions
and function names, with a consistent semantics.

Lambda expressions are often thought to denote "anonymous" functions, so
it may seem paradoxical to treat them as names.  The paradox is only
apparent, since the expression itself has the properties of a Lisp
function name: It is (typically) a cons tree which can be read, printed,
and stored in source files, and it denotes a well-defined Lisp function.

Benefit to Users:

Function names are useful for representing objects in remote
environments, because they need not be bound at all times to the same
function, or to any function, and because they are typically stable in
meaning across reads and prints, where plain functions are not.
Programs which deal simultaneously with remote and local environments,
such as CLOS, can probably be simplified, since function names
can be used uniformly, rather than an ad-hoc mixture of functions
and function names.

The language as a whole become more uniform from these additions and
clarifications, making it easier to learn and use.  (See Esthetics.)

Cost to Implementors:

Interpreters which currently have a special case check for application
of lambda expressions would need to modify this check to call
FDEFINITION when a list of any sort is encountered.  Note that all
Common Lisps already must perform some such check, since lambda
expressions can be funcalled (and this is currently a very special case,
the only standard case of a list being funcalled).  This means that
every Lisp already has a place to insert the required call to
FDEFINITION.

In some implementations, FDEFINITION of a lambda expression could be that
lambda-expression itself.  In others featuring a pre-eval codewalk, the
walk would be done by FDEFINITION, which would return an appropriate
closure.

Cost of Non-adoption:

Rather than two notions for function references (functions and function
names), there would be several notions, each corresponding to the valid
inputs for particular group of primitives.  APPLY and FUNCALL would
accept functions, symbolic names, and lambda expressions, but not setf
function names.  FDEFINITION and its kind would accept symbols and setf
function names but not lambda expressions.  If the :LARGE proposal is
not adopted, this fragmentation would also apply to the various syntaxes
involving function names; some names would be acceptable to DEFUN
but not to FLET, etc.

- - - - - - - - - - - - -
> 13. Declare that any function name is a suitable argument to FUNCALL and
>     APPLY.  In such a case, the function name is passed to FDEFINITION,
>     and the result (which may in turn be a function name) is called.

I don't think this is such a good idea.  The case of automatically coercing
a symbol to a function is needed because it provides a portable mechanism
for indirect addressing of a function; I haven't seen a reason to need this
for non-symbol function specs.  But more important is that coercing a
symbol to a function is a trivial operation that is reasonable to do at
run time on each call without adding a significant amount of overhead.
FDEFINITION, on the other hand, is a much more expensive operation -- at
best it might use GET to do a property list lookup, or it could be using
string-append and INTERN to convert the name to a symbol.  In either case,
I think this is more work than you want to do on each call.

> 12. Declare that any lamba expression (i.e., a list whose car is LAMBDA and
>     whose cdr is a well-formed lambda argument list and body) is a function
>     name.  The effects of the function name accessors on lambda expressions
>     are as follows.  FDEFINITION returns an implementation-defined value which
>     is the function specified the lambda expression, closed in the global
>     environment.  This FDEFINITION value cannot be changed by SETF.
>     FBOUNDP always returns T, and MAKUNBOUND is an error.

The exceptions for SETF and MAKUNBOUND show that this is not really as
consistent as you might like.  Furthermore, the FUNCTION special form would
have to treat a LAMBDA expression as a function, not a function name, in
order for it to be lexically scoped.  It seems like this might just cause
confusion rather than consistency.

∂16-Mar-89  2334	X3J13-mailer 	Issue LOOP-AND-DISCREPANCY, version 1    
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  23:34:11 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 89 23:32:03 PST
Date: 16 Mar 89 23:31 PST
From: masinter.pa@Xerox.COM
To: X3J13@sail.stanford.edu
Subject: Issue LOOP-AND-DISCREPANCY, version 1
line-fold: NO
Message-ID: <890316-233203-6953@Xerox>

!
Issue:		LOOP-AND-DISCREPANCY

References:	Loop Facility document X3J13/89-004

Related issues: 

Category:	CHANGE CLARIFICATION

Edit history:	Version 1, 15-Mar-88 by Steele

Problem description:

The treatment of the AND conjunction in FOR/AS and WITH clauses is not
consistent.  Examples of the use of WITH are also not consistent in this
respect.

Page 2-5 implies by example that when AND is used to join two
FOR/AS clauses, the word FOR or AS must occur after the word AND.

Page 2-31 has formal syntax specifying that when AND is used to join two
WITH clauses, the word WITH must *not* occur after the word AND.  Examples
on that page are consistent with this specification.

Page 2-41 has an example in which WITH is repeated after AND.


Proposal (LOOP-AND-DISCREPANCY:NO-REITERATION):

Let stand the formal syntax for WITH.

Change the description of FOR/AS clauses to specify that when
two or more such clauses are joined with AND, clauses after the
first do not have FOR or AS before them.

The complete formal syntax for FOR/AS may be described as follows:

for-as ::= {FOR | AS} for-as-subclause {AND for-as-subclause}*

for-as-subclause ::= for-as-arithmetic | for-as-in-list
		   | for-as-on-list | for-as-equals-then
		   | for-as-across | for-as-hash | for-as-package

for-as-arithmetic ::= var [type-spec] ...

and so on.

Examples:

> (loop for x from 1 to 10		;Corrected from X3J13/89-004, page 2-5
        and y = nil then x
        collect (list x y))
((1 NIL) (2 1) (3 2) (4 3) (5 4) (6 5) (7 6) (8 7) (9 8) (10 9))

> (loop with (a b) float = '(1.0 2.0)	;Corrected from X3J13/89-004, page 2-41
        and (c d) integer = '(3 4)
        and (e f)
        return (list a b c d e f))
(1.0 2.0 3 4 nil nil)


Rationale:

The treatment of AND should be internally consistent.  There is no reason
to repeat the FOR/AS keyword.  Not repeating the keyword emphasizes that
the subclauses are functionally linked under the heading of WITH or FOR.
(Compare to the third use of AND in LOOP, to link clauses controlled
by WHEN/IF/UNLESS.  One does not repeat the WHEN; rather, the clauses
grouped by AND are controlled by a single WHEN.)


Current practice:

Symbolics LOOP allows FOR to be included or omitted after AND,
with identical meanings.  WITH may not be repeated after AND.


Cost to Implementors: Small?

Cost to Users: Possible incompatibility with existing implementors' extensions.

Cost of non-adoption:  Utter confusion.

Performance impact:  None.

Benefits:  Consistent treatment of AND within LOOP.

Esthetics:

Absolutely none.  We're talking about LOOP here.

Discussion:

Steele supports this proposal.  It is a reversal of his previous
suggestion on the topic, thanks to feedback from Moon.



     ----- End Forwarded Messages -----

∂16-Mar-89  2330	X3J13-mailer 	Issue: LOAD-OBJECTS (Version 3)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 Mar 89  23:30:04 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 16 MAR 89 23:27:37 PST
Date: 16 Mar 89 23:26 PST
From: masinter.pa@Xerox.COM
Subject: Issue: LOAD-OBJECTS (Version 3)
To: x3j13@sail.stanford.edu
line-fold: NO
Message-ID: <890316-232737-6946@Xerox>


Version 1 was distributed in hardcopy form and discussed
at the January 1989 meeting.

Discussion so far has been considering alternatives of
load functions rather than load forms, or having two
generic functions.

!
Issue:         LOAD-OBJECTS

References:    none

Related issues: LOAD-TIME-EVAL,
                CONSTANT-COMPILABLE-TYPES,
                CONSTANT-CIRCULAR-COMPILATION

Category:      ADDITION

Forum:         Cleanup

Edit history:  Version 1, 2-Jan-89, by Moon (for discussion)
               Version 2, 13-Jan-89, by Moon (draft updated from discussion)
               Version 3,  9-Mar-89, by Moon (changes suggested by discussion)

Problem description:

  Common Lisp doesn't provide any way to use an object of a user-defined
  type (defined with DEFCLASS or DEFSTRUCT) as a constant in a program
  compiled with COMPILE-FILE.  The problem is that LOAD has to be able
  to "reconstruct" an equivalent object when the compiled-code file is
  loaded, but the programmer has no way to tell LOAD how to do that.


Proposal (LOAD-OBJECTS:MAKE-LOAD-FORM):
          
  Define a new generic function named MAKE-LOAD-FORM, which takes one
  argument and returns two values.  The argument is an object that is
  referenced as a constant or as a self-evaluating form in a file being
  compiled by COMPILE-FILE.  The objective is to enable LOAD to
  construct an equivalent object.

  The first value, called the "creation form," is a form that, when
  evaluated at load time, should return an object that is equivalent to
  the argument.  The exact meaning of "equivalent" depends on the type
  of object and is up to the programmer who defines a method for
  MAKE-LOAD-FORM.  This is the same type of equivalence discussed
  in issue CONSTANT-COMPILABLE-TYPES.

  The second value, called the "initialization form," is a form that,
  when evaluated at load time, should perform further initialization of
  the object.  The value returned by the initialization form is ignored.
  If the MAKE-LOAD-FORM method returns only one value, the
  initialization form is NIL, which has no effect.  If the object used
  as the argument to MAKE-LOAD-FORM appears as a constant in the
  initialization form, at load time it will be replaced by the
  equivalent object constructed by the creation form; this is how the
  further initialization gains access to the object.

  Both the creation form and the initialization form can contain
  references to objects of user-defined types (defined precisely below).
  However, there must not be any circular dependencies in creation forms.
  An example of a circular dependency is when the creation form for the
  object X contains a reference to the object Y, and the creation form
  for the object Y contains a reference to the object X.  A simpler
  example would be when the creation form for the object X contains
  a reference to X itself.  Initialization forms are not subject to
  any restriction against circular dependencies, which is the entire
  reason that initialization forms exist.  See the example of circular
  data structures below.

  The creation form for an object is always evaluated before the
  initialization form for that object.  When either the creation form or
  the initialization form references other objects of user-defined types
  that have not been referenced earlier in the COMPILE-FILE, the
  compiler collects all of the creation and initialization forms.  Each
  initialization form is evaluated as soon as possible after its
  creation form, as determined by data flow.  If the initialization form
  for an object does not reference any other objects of user-defined
  types that have not been referenced earlier in the COMPILE-FILE, the
  initialization form is evaluated immediately after the creation form.
  If a creation or initialization form F references other objects of
  user-defined types that have not been referenced earlier in the
  COMPILE-FILE, the creation forms for those other objects are evaluated
  before F, and the initialization forms for those other objects are
  also evaluated before F whenever they do not depend on the object
  created or initialized by F.  Where the above rules do not uniquely
  determine an order of evaluation, which of the possible orders of
  evaluation is chosen is unspecified.

  While these creation and initialization forms are being evaluated, the
  objects are possibly in an uninitialized state, analogous to the state
  of an object between the time it has been created by ALLOCATE-INSTANCE
  and it has been processed fully by INITIALIZE-INSTANCE.  Programmers
  writing methods for MAKE-LOAD-FORM must take care in manipulating
  objects not to depend on slots that have not yet been initialized.

  It is unspecified whether LOAD calls EVAL on the forms or does some
  other operation that has an equivalent effect.  For example, the
  forms might be translated into different but equivalent forms and
  then evaluated, they might be compiled and the resulting functions
  called by LOAD, or they might be interpreted by a special-purpose
  interpreter different from EVAL.  All that is required is that the
  effect be equivalent to evaluating the forms.

  COMPILE-FILE calls MAKE-LOAD-FORM on any object that is referenced as
  a constant or as a self-evaluating form, if the object's metaclass is
  STANDARD-CLASS, STRUCTURE-CLASS, any user-defined metaclass (not a
  subclass of BUILT-IN-CLASS), or any of a possibly-empty
  implementation-defined list of other metaclasses.  COMPILE-FILE will
  only call MAKE-LOAD-FORM once for any given object (compared with EQ)
  within a single file.

  It is valid for user programs to call MAKE-LOAD-FORM in other
  circumstances, providing the argument's metaclass is not BUILT-IN-CLASS
  or a subclass of BUILT-IN-CLASS.

  Define a new function named MAKE-LOAD-FORM-USING-SLOTS, which takes
  one required argument and one optional argument and returns two
  values.  This can be useful in user-written MAKE-LOAD-FORM methods.
  The first argument is the object.  The optional second argument is a
  list of the names of the slots to preserve; it defaults to all of the
  local slots.  MAKE-LOAD-FORM-USING-SLOTS returns forms that construct
  an equivalent object using MAKE-INSTANCE and SETF of SLOT-VALUE for
  slots with values, or SLOT-MAKUNBOUND for slots without values, or
  using other functions of equivalent effect.
  MAKE-LOAD-FORM-USING-SLOTS returns two values, thus it can deal with
  circular structures.  MAKE-LOAD-FORM-USING-SLOTS works for any object
  of metaclass STANDARD-CLASS or STRUCTURE-CLASS.  Whether the result is
  useful in an application depends on whether the object's type and slot
  contents fully capture the application's idea of the object's state.

  MAKE-LOAD-FORM of an object of metaclass STANDARD-CLASS or
  STRUCTURE-CLASS for which no user-defined method is applicable signals
  an error.  It is valid to implement this either by defining default
  methods on STANDARD-OBJECT and STRUCTURE-OBJECT that signal an error
  or by having no applicable method for those classes.


Examples:

  ;; Example 1
  (defclass my-class ()
     ((a :initarg :a :reader my-a)
      (b :initarg :b :reader my-b)
      (c :accessor my-c)))
  (defmethod shared-initialize ((self my-class) ignore &rest ignore)
    (unless (slot-boundp self 'c)
      (setf (my-c self) (some-computation (my-a self) (my-b self)))))
  (defmethod make-load-form ((self my-class))
    `(make-instance ',(class-name (class-of self))
                    :a ',(my-a self) :b ',(my-b self)))

  In this example, an equivalent instance of my-class is reconstructed
  by using the values of two of its slots.  The value of the third slot
  is derived from those two values.

  Another way to write the last form in the above example would have been

  (defmethod make-load-form ((self my-class))
     (make-load-form-using-slots self '(a b)))

  ;; Example 2
  (defclass my-frob ()
     ((name :initarg :name :reader my-name)))
  (defmethod make-load-form ((self my-frob))
    `(find-my-frob ',(my-name self) :if-does-not-exist :create))

  In this example, instances of my-frob are "interned" in some way.
  An equivalent instance is reconstructed by using the value of the
  name slot as a key for searching existing objects.  In this case
  the programmer has chosen to create a new object if no existing
  object is found; alternatively she could have chosen to signal an
  error in that case.

  ;; Example 3
  (defclass tree-with-parent () ((parent :accessor tree-parent)
                                 (children :initarg :children)))
  (defmethod make-load-form ((x tree-with-parent))
    (values
      ;; creation form
      `(make-instance ',(class-of x) :children ',(slot-value x 'children))
      ;; initialization form
      `(setf (tree-parent ',x) ',(slot-value x 'parent))))

  In this example, the data structure to be dumped is circular, because
  each parent has a list of its children and each child has a reference
  back to its parent.  Suppose make-load-form is called on one object in
  such a structure.  The creation form creates an equivalent object and
  fills in the children slot, which forces creation of equivalent
  objects for all of its children, grandchildren, etc.  At this point
  none of the parent slots have been filled in.  The initialization form
  fills in the parent slot, which forces creation of an equivalent
  object for the parent if it was not already created.  Thus the entire
  tree is recreated at load time.  At compile time, MAKE-LOAD-FORM is
  called once for each object in the true.  All of the creation forms
  are evaluated, in unspecified order, and then all of the
  initialization forms are evaluated, also in unspecified order.

  ;; Example 4
  (defstruct my-struct a b c)
  (defmethod make-load-form ((s my-struct))
     (make-load-form-using-slots s))

  In this example, the data structure to be dumped has no special
  properties and an equivalent structure can be reconstructed
  simply by reconstructing the slots' contents.


Rationale:

  Only the programmer who designed a class can know the correct
  way to reconstruct objects of that class at load time, therefore
  the reconstruction should be controlled by a generic function.
  Using EVAL as the interface for telling LOAD what to do provides
  full generality.

  MAKE-LOAD-FORM returns two values so that circular structures can
  be handled.  If CONSTANT-CIRCULAR-COMPILATION is rejected,
  MAKE-LOAD-FORM will only return one value, although implementations
  that make an extension to support circular constants will probably
  also make the extension to accept two values from MAKE-LOAD-FORM.

  The default for class objects and structures is to signal an error,
  rather than picking some particular object reconstruction technique,
  because no reconstruction technique is appropriate for all objects.
  It only takes two lines of code, as in example 4, to instruct the
  compiler to use the technique that most often has been suggested
  as the default.

  MAKE-LOAD-FORM has a natural resemblance to PRINT-OBJECT, as a hook
  for the programmer to control the system's actions.

  The order of evaluation rules for creation and initialization forms
  eliminate the possibility of partially initialized objects in the
  absence of circular structures, and reduce it to the minimum possible
  in the presence of circular structures.  This allows nodes in
  non-circular structures to be built out of fully initialized subparts.


Current practice:

  Symbolics Flavors has something like this, but under a different name.
  The name Symbolics uses is not suitable for standardization.

  JonL reports that Lucid is getting more and more requests for this.

Cost to Implementors:

  This seems like only a few one-line changes in the compiled-code
  file writer and reader.  MAKE-LOAD-FORM-USING-SLOTS is a couple
  dozen lines of code, assuming the presence of the CLOS metaobject
  protocol or an implementation-dependent equivalent.

Cost to Users:

  None.

Cost of non-adoption:

  Serious impairment of the ability to use extended-type objects.  Each
  implementation will probably make up its own version of this as an
  extension.

Performance impact:

  None.

Benefits:

  See Cost of non-adoption.

Esthetics:

  No significant positive or negative impact.

Discussion:

  It would be possible to define an additional level of protocol that
  allows multiple classes to contribute to the reconstruction of an
  object, combining initialization arguments contributed by each class.
  Since a user can easily define that in terms of MAKE-LOAD-FORM without
  modifying the Lisp system, it is not being proposed now.

  Any type that has a read syntax is likely to appear as a quoted
  constant or inside a quoted constant.  Pathnames are one example, user
  programs often define others.  Also many implementations provide a way
  to create a compiled-code file full of data (rather than compiled Lisp
  programs), and such data probably include extended-type objects.

  Moon supports this.  David Gray and John Rose made major contributions
  to the discussion that produced this improved version 2 proposal.



     ----- End Forwarded Messages -----

∂17-Mar-89  0009	X3J13-mailer 	Issue: REAL-NUMBER-TYPE (version 3) 
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89  00:08:54 PST
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAR 89 23:50:31 PST
Date: 16 Mar 89 23:49 PST
From: masinter.pa@Xerox.COM
Subject: Issue: REAL-NUMBER-TYPE (version 3)
To: x3J13@Sail.Stanford.EDU
Message-ID: <890316-235031-6996@Xerox>

!
Issue:        REAL-NUMBER-TYPE
Forum:	      CLEANUP
References:   Table 4-1.
Category:     ADDITION
Edit history: 04-JAN-89, Version 1 by Bob Cassels, Don Sakahara, Kent Pitman,
                         and John Aspinall
              08-JAN-89, Version 2 by Bob Cassels -- incorporate
                         Masinter's suggestion and make REAL a CLOS class
              13-JAN-89, Version 3 by Cassels and Aspinall -- incorporate Marc LeBrun's
                         suggestions clarifying the relationship between CL
                         numeric type names and mathematical names
Status:	      For Internal Discussion

Problem Description:

  There is no standard type specifier symbol for the CL type
  '(OR RATIONAL FLOAT). 

Proposal (REAL-NUMBER-TYPE:REAL):

  Make REAL be a CL data type:

  p.13 "Numbers"

    Add:     The NUMBER data type encompasses all of these kinds of
             numbers.  For convenience, there are names for some
             subclasses of numbers.  @i[Integers] and @i[ratios] are of
             type RATIONAL.  @i[Rational numbers] and @[floating-point
             numbers] are of type REAL.  @i[Real numbers] and @i[complex
             numbers] are of type NUMBER.

	     Although the names of these types were chosen with the
	     terminology of mathematics in mind, the correspondences
	     are not always exact.  Integers and ratios model the
	     corresponding mathematical concepts directly.  Numbers
	     of the FLOAT type may be used to approximate real
	     numbers, both rational and irrational.  The REAL type
	     includes all Common Lisp numbers which represent
	     mathematical real numbers, though there are
	     mathematical real numbers (irrational numbers)
	     which do not have an exact Common Lisp representation.
	     Only REAL numbers may be ordered using the <, >, <=,
	     and >= functions.

             Compatibility note:  The Fortran standard defines the term
             "real datum" to mean "a processor approximation to the value
             of a real number."  In practice the Fortran "basic real" type
             is the floating-point data type Common Lisp calls
             SINGLE-FLOAT.  The Fortran "double precision" type is
             Common Lisp's DOUBLE-FLOAT.  The Pascal "real" data type is
             an "implementation-defined subset of the real numbers."  In
             practice this is usually a floating-point type, often what
             Common Lisp calls DOUBLE-FLOAT.

             A translation of an algorithm written in Fortran or Pascal
             which uses "real" data usually will use some appropriate
             precision of Common Lisp's FLOAT type.  Some algorithms may
             gain accuracy and/or flexibility by using Common Lisp's
             RATIONAL or REAL types instead.

  p.33 "Overlap, Inclusion, and Disjointness of Types":

    Remove:  The types RATIONAL, FLOAT, and COMPLEX are pairwise
             disjoint subtypes of NUMBER.

             Rationale: It might be thought that INTEGER and RATIO ...

             Rationale: It might be thought that FIXNUM and BIGNUM ...

    Add:     The types RATIONAL and FLOAT are pairwise disjoint subtypes
             of REAL.

             The types REAL and COMPLEX are pairwise disjoint subtypes
             of NUMBER.

             Rationale: It might be thought that FIXNUM and BIGNUM should 
             form an exhaustive partition of the type INTEGER, that INTEGER
             and RATIO should form an exhaustive partition of RATIONAL,
             that RATIONAL and FLOAT should form an exhaustive partition of 
             REAL, and that REAL and COMPLEX should form an exhaustive
             partition of NUMBER.  These are all purposely avoided in order 
             to permit compatible experimentation with extensions to the
             Common Lisp number system, such as the idea of adding explicit 
             representations of infinity or of positive and negative infinity.

   p.43 Table 4-1 "Standard Type Specifier Symbols"

    Add:     REAL

   p.49 "Type Specifiers that Abbreviate"

     Add:    (REAL low high)
             Denotes the set of real numbers between low and high.  ...
             [As with RATIONAL and FLOAT.]


  Make REAL a built-in CLOS class.

Proposal (REAL-NUMBER-TYPE:REALP):

  Add a specific data type predicate REALP which tests for membership in
  this type.  [By analogy with NUMBERP.]

Test Case:

  If a programmer wishes to test for "a number between 1 and 10", the
  only current CL types would be '(or (rational 1 10) (float 1 10)) or
  something like '(and numberp (not complexp) (satisfies range-1-10))
  with (defun range-1-10 (real) (<= 1 real 10)).  Both of these are
  likely less efficient, and certainly less expressive than '(real 1 10).

Rationale:

  Mathematics has a name for (OR RATIONAL FLOAT) -- it is "real".
  This class is important because it is all the numbers which can be
  ordered.

  Throughout the "Numbers" chapter, the phrase "non-complex number" is
  used.
  MAX, MIN, p. 198 "The arguments may be any non-complex numbers."
  CIS p. 207 "The argument ... may be any non-complex number."

Current Practice:

  Probably nobody does this.
  
Cost to Implementors:

  Some work is necessary to add this name.  But since the underlying
  type already exists the amount of work should be minimal.
  
Cost to Users:

  Since this is an upward-compatible extension, it may be ignored by
  users.

Cost of Non-Adoption:

  Occasional inconvenience and/or inefficiency.

Benefits:

  Mathematical clarity.

  Ability to do CLOS method dispatch on the type.

Aesthetics:

  As mentioned under "rationale," this would be a more concise way to
  express a common programming idiom.

Discussion:

  The name "non-complex number" is incorrect because future
  implementations may wish to include numerical types which are neither
  complex nor real.  [e.g. pure imaginary numbers or quaternions]
  
  The name "scalar" is incorrect because the mathematical concept of
  scalar may indeed include complex numbers.

  Fortran and Pascal use the name "real" to mean what CL calls
  SINGLE-FLOAT.  That should cause no significant problem, since a Lisp
  program written using the type REAL will do mathematically what the
  equivalent Fortran program would do.  This is because Fortran's "real"
  data-type is a subtype of the CL REAL type.  The only differences
  might be that the Lisp program could be less efficient and/or more
  accurate.

  A survey of several Fortran and Pascal books shows that the distinction
  between INTEGER and REAL is that REAL numbers may have fractional
  parts, while INTEGERs do not.  Later discussions explain that REALs
  cover a greater range.  Much later discussions cover precision
  considerations, over/underflow, etc.  So the average Fortran or Pascal
  programmer should be completely comfortable with the proposed Lisp
  concept of REAL.

∂17-Mar-89  0817	X3J13-mailer 	Issue: COERCE-INCOMPLETE (Version 3)
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89  08:17:09 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Fri, 17 Mar 89 10:56:55 EST
Date: Fri, 17 Mar 89 10:57 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Issue: COERCE-INCOMPLETE (Version 3)
To: Kent M Pitman <KMP@stony-brook.scrc.symbolics.com>
Cc: masinter.pa@xerox.com, x3j13@sail.stanford.edu
In-Reply-To: <890316191820.6.KMP@BOBOLINK.SCRC.Symbolics.COM>
Message-Id: <19890317155747.8.BARMAR@OCCAM.THINK.COM>

    Date: Thu, 16 Mar 89 19:18 EST
    From: Kent M Pitman <KMP@stony-brook.scrc.symbolics.com>

	Date: Thu, 16 Mar 89 18:00 EST
	From: Barry Margolin <barmar@Think.COM>

	...
	Problem with DEPRECATE: Didn't we specify that the way to convert a
	lambda expression into a function object is to use (COERCE x 'FUNCTION)?
	Or did we also define a new function that does this?

    Re-read FUNCTION-TYPE. The thing Beckerle really wanted and finally
    got (over my objection) was that COERCE did nothing `hard' ... What
    it ended up being able to be do can be expressed by #'IDENTITY and
    #'SYMBOL-FUNCTION.

     (COERCE x 'FUNCTION) ==
     (ETYPECASE X
       (SYMBOL   (SYMBOL-VALUE X))
       (FUNCTION X))

    I don't really think anything more needs to be provided, even if we
    DEPRECATE coerce.

I can't find my copy of FUNCTION-TYPE, but I remember it being amended
to add coercion of lambda expressions to functions.  Maybe my memory is
faulty, but I remember something like

(COERCE X 'FUNCTION) ==
(ETYPECASE X
  (SYMBOL (SYMBOL-FUNCTION X))
  (FUNCTION X)
  ((SATISFIES LAMBDA-EXP-P) (EVAL `(FUNCTION ,X))))
      
(DEFUN LAMBDA-EXP-P (X)
  (AND (CONSP X)		; a non-null list
       (EQ (CAR X) 'LAMBDA)	; beginning with LAMBDA
       (NOT (NULL (CDR X)))	; with at least two elements
       (LISTP (CADR X))))	; argument list is a list

                                                barmar

∂17-Mar-89  0834	X3J13-mailer 	Issue: LOCALLY-TOP-LEVEL (Version 2)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 17 Mar 89  08:34:33 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 559504; Fri 17-Mar-89 11:31:57 EST
Date: Fri, 17 Mar 89 11:31 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: LOCALLY-TOP-LEVEL (Version 2)
To: X3J13@sail.stanford.edu
References: <19890309233609.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890317163159.3.MOON@EUPHRATES.SCRC.Symbolics.COM>

This is a cleanup committee issue.  It could have been in the
compiler committee, but as it happens it ended up in the
cleanup committee.

Issue:         LOCALLY-TOP-LEVEL

References:    None

Related issues: EVAL-WHEN-NON-TOP-LEVEL, DECLARATION-SCOPE

Category:      CLARIFICATION / ADDITION

Edit history:  Version 1,  9-Mar-89, by Moon
               Version 2, 16-Mar-89, by Moon, fix referenced proposal name

Problem description:

  It is desirable to be able to wrap LOCALLY around one or more
  top-level forms and have them continue to be treated as top-level
  forms.  Three examples of how this is useful:

   - to put an OPTIMIZE or INLINE declaration into force around
     several related forms.

   - to put declarations into force around DEFCLASS, or any other
     top-level form that lacks a syntax for embedded declarations.

   - DECLARATION-SCOPE:NO-HOISTING, which passed in January,
     removed the ability to use a DECLARE at the head of the body of a
     DEFUN or DEFMACRO to make a declaration that applies to the entire
     form, including the lambda-list.  We are supposed to use LOCALLY
     instead, but forms in the body of LOCALLY are not top-level,
     and that changes the semantics of DEFMACRO.

  Issue EVAL-WHEN-NON-TOP-LEVEL could not define LOCALLY to treat
  its body as top-level forms, because only a special form can do
  that and LOCALLY is a macro.

Proposal (LOCALLY-TOP-LEVEL:SPECIAL-FORM):
          
  Change LOCALLY from a macro to a special form, and change the
  definition of compiler processing (in EVAL-WHEN-NON-TOP-LEVEL)
  so that when a LOCALLY form appears at top level the forms in
  its body are processed at top level.

Examples:

  (locally (declare (optimize (safety 3) (space 3) (speed 0)))
    (defmacro frob (&environment e x y &optional (z (foo x y)))
      (mumble x y z e)))

  Without this proposal, this would have to be written

  (defmacro frob (&environment e x y &optional (z (locally
                                                    (declare
                                                      (optimize
                                                        (safety 3)
                                                        (space 3)
                                                        (speed 0)))
                                                    (foo x y))))
    (locally (declare (optimize (safety 3) (space 3) (speed 0)))
      (mumble x y z e)))

Rationale:

  Wrapping LOCALLY around a form should not change its semantics except
  as specified by the declarations, hence the body of a top-level
  LOCALLY should be top-level.

  A macro cannot have a top-level body unless it expands into a special
  form that has a top-level body; otherwise the macro invocation and
  the macro expansion would not have identical semantics as top-level
  forms.  There is no available special form for LOCALLY to macroexpand
  into (CLtL doesn't say, but presumably the intent was to expand into
  a LET with an empty binding list).

Current practice:

  The Zetalisp equivalent of LOCALLY worked to surround top-level forms,
  because it was a macro that expanded into COMPILER-LET (stashing the
  declarations in a special variable the compiler would look at).  This
  is of course the wrong way to do declarations, but it shows that the
  idea was that you could wrap declarations around a bunch of top-level
  forms.

  Symbolics Genera 7.4.0 does not implement the proposal (but it does
  not implement DECLARATION-SCOPE:NO-HOISTING either).  I did
  not survey any other implementations.

Cost to Implementors:

  A half dozen lines of code in the compiler and a smaller amount
  in the interpreter and any program-analyzing programs.

Cost to Users:

  None.

Cost of non-adoption:

  See the horrible example above.

Performance impact:

  None.

Benefits:

  More consistent language.

Esthetics:

  Improved.

Discussion:

  None.

∂17-Mar-89  0857	X3J13-mailer 	Re: Issue: COERCE-INCOMPLETE (Version 3) 
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 17 Mar 89  08:57:27 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA01151; Fri, 17 Mar 89 09:54:54 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA06800; Fri, 17 Mar 89 09:54:37 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903171654.AA06800@defun.utah.edu>
Date: Fri, 17 Mar 89 09:54:35 MST
Subject: Re: Issue: COERCE-INCOMPLETE (Version 3)
To: Barry Margolin <barmar@Think.COM>
Cc: Kent M Pitman <KMP@stony-brook.scrc.symbolics.com>, masinter.pa@xerox.com,
        x3j13@sail.stanford.edu
In-Reply-To: Barry Margolin <barmar@Think.COM>, Fri, 17 Mar 89 10:57 EST

BarMar is right.  I have a hardcopy of the FUNCTION-TYPE writeup that
was mailed on 4 Sep 88, with a note from Larry indicating that it's
the final version as passed at the June meeting.  It includes
COERCE'ing of lambda expressions to functions as item 6b.

Personally, I don't think this is a valid argument for not getting rid
of COERCE, since it is easy to coerce a lambda expression to a function
using (EVAL `(FUNCTION ,x)).

-Sandra
-------

∂17-Mar-89  0854	X3J13-mailer 	Re: Issue: COERCE-INCOMPLETE (Version 3) 
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89  08:53:52 PST
Received: from Salvador.ms by ArpaGateway.ms ; 17 MAR 89 08:48:52 PST
Date: 17 Mar 89 08:47 PST
From: masinter.pa@Xerox.COM
Subject: Re: Issue: COERCE-INCOMPLETE (Version 3)
In-reply-to: Barry Margolin <barmar@Think.COM>'s message of Fri, 17 Mar 89
 10:57 EST
To: Barry Margolin <barmar@Think.COM>
cc: x3j13@sail.stanford.edu
Message-ID: <890317-084852-8321@Xerox>

I sent you a copy of FUNCTION-TYPE, as amended and passed. There was
discussion of an amendment to allow coercion of lambda expressions to
functions, but the decision at the June 88 X3J13 meeting was to not require
such coercions.


Most of the issues passed so far are available from arisia.xerox.com
clcleanup/passed. Some of the issues that were amended at the last meeting
haven't yet been stored 'as amended'. I hope to have them there in the next
few days, as well as copies of all of the 'pending' issues.

∂17-Mar-89  1041	X3J13-mailer 	Issue: PACKAGE-FUNCTION-CONSISTENCY, V.3 
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89  10:40:58 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 17 MAR 89 10:28:12 PST
Date: 17 Mar 89 10:25 PST
From: masinter.pa@Xerox.COM
Subject: Issue: PACKAGE-FUNCTION-CONSISTENCY, V.3
To: x3J13@sail.stanford.edu
cc: masinter.pa@Xerox.COM
Message-ID: <890317-102812-1247@Xerox>

The notes from the January meeting said Accepted MORE-PERMISSIVE (v2),
as amended. Amendments made at the meeting added DELETE-PACKAGE and
 DEFPACKAGE  to the list of functions and removed the paragraph beginning
with the words "If IN-PACKAGE...".

I can't figure out where a package name *isn't* allowed in DEFPACKAGE
or where a package object would make sense. Are the notes incorrect,
or were we just to hasty?

Anyway, here's my guess at what we really meant to pass; I suppose
we can just vote this one in instead.

!
Issue:        PACKAGE-FUNCTION-CONSISTENCY
References:   11.7 Package System Functions and Variables (pp182-188)
Category:     CLARIFICATION/CHANGE
Edit history: 21-Oct-88, Version 1 by Pitman
		12-Jan-89, Version 2 by Masinter (add MORE-PERMISSIVE option)
		17-Mar-89, Version 3, by Masinter, MORE-PERMISSIVE as
			amended & adopted at Jan 89 X3j13

Problem Description:

  CLtL is vague about whether either or both of package or package name
  are permissible in some cases.

Proposal (PACKAGE-FUNCTION-CONSISTENCY:MORE-PERMISSIVE):

  Clarify that it is permissible to pass either a package object
  or a package name (symbol or string) in the following situations:
    - the :USE argument to MAKE-PACKAGE or IN-PACKAGE
    - the first argument to IN-PACKAGE, FIND-PACKAGE, RENAME-PACKAGE
			or DELETE-PACKAGE
    - the second argument to INTERN, FIND-SYMBOL, UNINTERN
    - the second argument to EXPORT, UNEXPORT, IMPORT,
      SHADOWING-IMPORT, and SHADOW
    - the first argument (or a member of the list which is the first
      argument) to USE-PACKAGE or UNUSE-PACKAGE.
    - the PACKAGE argument to DO-SYMBOLS.
    - the PACKAGE argument to DO-EXTERNAL-SYMBOLS.
    - the PACKAGE argument to DO-ALL-SYMBOLS.

  If FIND-PACKAGE is given a package object as an argument, it simply
  returns it.

  Clarify that the functions PACKAGE-NAME, PACKAGE-NICKNAMES, 
  PACKAGE-USE-LIST, and PACKAGE-USED-BY-LIST are (at least conceptually)
  accessors to package data structures and permit only package objects
  as arguments.

  Clarify that the function MAKE-PACKAGE permits only a package name
  as an argument since it does not make sense to create an existing
  package.

  Clarify that package nicknames must always be expressed as package
  names (symbols or strings) and may never be actual package objects.

In addition, require that PACKAGE-NAME, PACKAGE-NICKNAMES, 
PACKAGE-USE-LIST, and PACKAGE-USED-BY-LIST  to accept names,
too.

Examples:

  (INTERN "FOO" "KEYWORD") => :FOO

  (DEFVAR *FOO-PACKAGE* (MAKE-PACKAGE "FOO"))
  (RENAME-PACKAGE "FOO" "FOO0")
  (PACKAGE-NAME *FOO-PACKAGE*) => "FOO0"


  (PACKAGE-NAME "SYS") might return "SYSTEM".

Rationale:

   This makes things more consistent.
   It also adds a generally useful capability.


Current Practice:

  Symbolics Genera & Lucid permits strings as package names.
  Symbolics Cloe does not permit strings as package names.
  In Lucid FIND-PACKAGE and IN-PACKAGE require names.

Cost to Implementors:

  Small.

Cost to Users:

  None. This change is upward compatible.

Cost of Non-Adoption:

  Implementations would continue to vary gratuitously, leaving a potential
  for portability problems.

Benefits:

  The cost of non-adoption is avoided.

Aesthetics:

  This makes things more regular, and so presumably more aesthetic.

Discussion:

  Pitman ran across this problem while trying to port Macsyma to various
  implementations. Discussion with other maintainers of portable programs
  shows this is a common source of aggravation in portable code.

  Since the pathname accessors all take namestrings or streams, one might
  easily argue that it would be more consistent for PACKAGE-NAME, 
  PACKAGE-NICKNAMES, etc. to also take arguments of package names. After
  all,
   (PACKAGE-NAME "FOO") => "FOO"
  is no stranger than
   (NAMESTRING "JOE:fred.lisp") => "JOE:fred.lisp".

  It would be possible to say that MAKE-PACKAGE took package objects as
  arguments and just returned that package. That might have limited
  usefulness on rare occassions, but mostly seemed too far out in left
  field to bother suggesting it.

∂17-Mar-89  1223	X3J13-mailer 	**DRAFT** issue SYNTACTIC-ENVIRONMENT-ACCESS (version 4)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 17 Mar 89  12:23:14 PST
Received: from blacksox ([192.9.201.39]) by heavens-gate.lucid.com id AA00913g; Wed, 15 Mar 89 12:36:51 PST
Received: by blacksox id AA00297g; Wed, 15 Mar 89 12:40:06 PST
Date: Wed, 15 Mar 89 12:40:06 PST
From: Eric Benson <eb@lucid.com>
Message-Id: <8903152040.AA00297@blacksox>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
Cc: cl-compiler@sail.stanford.edu, x3j13@sail.stanford.edu
In-Reply-To: David A. Moon's message of Tue, 14 Mar 89 18:41 EST <19890314234118.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: **DRAFT** issue SYNTACTIC-ENVIRONMENT-ACCESS (version 4)

   Date: Tue, 14 Mar 89 18:41 EST
   From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>

   This looks good so far.  A few comments that might help you
   along with the draft:

   ...

   The :MACRO argument to AUGMENT-ENVIRONMENT shouldn't look like the CADR
   of a MACROLET special form, instead it should be a list of lists (name
   function).  That is, the expander functions should be supplied in the
   form of functions rather than in the form of the source text used by
   MACROLET.  Your rationale argues against this but I strongly believe
   that the rationale is wrong.  I wouldn't mind seeing the parsing portion
   of MACROLET made available as a separate function.

A small point: Shouldn't this be an a-list of the form
(name . function) instead of a list of lists?

∂17-Mar-89  1214	CL-Cleanup-mailer 	Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 17 Mar 89  12:14:37 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA01413g; Wed, 15 Mar 89 23:32:00 PST
Received: by bhopal id AA11607g; Wed, 15 Mar 89 23:32:47 PST
Date: Wed, 15 Mar 89 23:32:47 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8903160732.AA11607@bhopal>
To: cl-cleanup@sail.stanford.edu
Cc: X3J13@Sail.stanford.edu
In-Reply-To: masinter.pa@Xerox.COM's message of 15 Mar 89 05:13 PST <890315-051405-3472@Xerox>
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)

Although I haven't had time to join the overly-lengthy discussion on this
matter,  I did point out one particularly confusing direction -- that this
proposal to "fix" the function ADJUST-ARRAY has become a proposal to alter 
the semantics of the type SIMPLE-ARRAY.  Compare CLtL, p28, with the
sentence in the Rationale Section:
  "Specifying the points left unspecified (requiring all simple arrays to be
   non-adjustable and all adjustable arrays to be non-simple) would require
   large changes to some implementations and would be of little benefit to
   ..."
and with an item in the Clarification section:
  "a. Whether an array can be both simple and adjustable is unspecified."
[CLtL definition *does* specify it].

I suggested that a simple statement be added to the proposal as follows:
  "This proposal does not attempt to alter the meaning of the type
   SIMPLE-ARRAY in any way"
Moon expressed approval of adding that statement.

Altered semantics would mean that it is no longer a portable type.  I 
have sent out several trivially small examples that show this.  Some 
people have interpreted those examples as simply showing what happens 
with "broken" code; but quite to the contrary, they show how code can be 
"correct" on one implementation and "broken" on another ****** when the 
definition of SIMPLE-ARRAY is allowed to vary between one implementation 
and the other ******.  Very carefully, CLtL spells out that implementations 
may vary on the efficiency with which they implement SIMPLE-ARRAYS; but 
nowhere does it provide for optional exclusion of some parts of the 
definition thereof.


Also, I note that all of the discussion on the Cl-cleanup list was by
persons other than the half-dozen or so maintainers of "stock hardware"
compilers.  I personally spoke with three others (not including myself)
at Hawaii, and we all have identical requirements for the type SIMPLE-ARRAY,
and identical resolve that it must not be changed.  Our compilers will
continue to offer this C-level optimization capability; the only 
question is whether or not the CL1989 Standard will be cognizant of it.



-- JonL --

∂17-Mar-89  1223	X3J13-mailer 	Issue ERROR TERMINOLOGY   
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 17 Mar 89  12:23:02 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA01029g; Wed, 15 Mar 89 14:13:57 PST
Received: by challenger id AA12685g; Wed, 15 Mar 89 14:07:47 PST
Date: Wed, 15 Mar 89 14:07:47 PST
From: Richard P. Gabriel <rpg@lucid.com>
Message-Id: <8903152207.AA12685@challenger>
To: x3j13@sail.stanford.edu
Subject: Issue ERROR TERMINOLOGY


Is it the case that ``fatal'' is well-defined? If so, ``harmless'' is
simply something that is not fatal. According to my mathematics
education, that renders the term well-defined.

``Indeed, there is no way to invoke GC in Common Lisp and with a few
exceptions such as messages, GC must have NO side effects.''

Unsolicited messages can happen, and there is a proposal on the
cl-editorial table to render them harmless. If GC can have no side
effects, then why not state that and not wonder about unsolicited
messages? If we did that, then any Common Lisp that does print a
progress note is *out* of conformance. 

Also, as I've said several times, rehashing, termination of processes,
progress messages, flushing IO buffers, closing streams, and a list of
possibly hundreds of things are side effects of GC that should be
guaranteed harmless (that is, not fatal).

``> Some things are not immediately harmful but may cause
> trouble later on.

Yes, lots of things are that way.''

The definition of fatal puts no time constraints on the fatality. Therefore,
neither does its negation.

``> By ``unpredictable but harmless'', I think we are in effect saying
> ``not completely unpredictable''.  That is, we promise something but
> don't quite say what it is.  For example, Lisp will presumably not
> break off and start playing chess.  But maybe it's harmless to start
> playing chess.''

The beauty of a specification is knowing what not to say in order to
allow rational interpreters the freedom to interpret rationality now
and in the unpredictable future. There is considerable genius in the
fine line that Steele tread in CLtL on this. Does anyone rationally
think that a Common Lisp would be taken seriously that while GCing
broke out in a game of chess or an Irish gig? I refuse to seriously
debate with anyone who would use that as an example of something that
we must utter one word in the specification to prevent.

``As far as I can see, the only reasonable option is to specify
some range of possible consequences.  The constraints, whatever
they may be, make it possible to reason about what the program
will do.''

The reason this won't easily work is that it presumes that we are able
to accurately predict future implementation techniques and even to
fully comprehend current ones. I'm sure that KMP or I could supply an
endless stream of new and bizarre cases that have to be explicitly
dealt with. (I single out KMP because he has uncanny creativity.)

But, I'll change the debate a little. I've claimed that ``harmless''
is well-defined if and only if ``fatal'' is well-defined or at least
defined well enough. So, to convince me that ``harmless'' should be
pitched, you must convince me that ``fatal'' must be pitched.

			-rpg-

∂17-Mar-89  1223	X3J13-mailer 	issue SAFE-CODE, version 1
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 17 Mar 89  12:22:54 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA01090g; Wed, 15 Mar 89 14:31:11 PST
Received: by challenger id AA12754g; Wed, 15 Mar 89 14:25:03 PST
Date: Wed, 15 Mar 89 14:25:03 PST
From: Richard P. Gabriel <rpg@lucid.com>
Message-Id: <8903152225.AA12754@challenger>
To: cl-compiler@sail.stanford.edu, x3j13@sail.stanford.edu
Subject: issue SAFE-CODE, version 1


According to my understanding of the dictionary definitions,
``unsafe'' means primarily ``the opposite or reversal of `safe' '' and
secondarily ``not safe.'' This coincides with Moon's reading.
Therefore, I propose we use the term ``nonsafe'' which clearly means
``not safe.''  This, coupled with the already very explicit definition
of ``unsafe,'' which explains that unsafe code might actually be safe,
should take care of his objection.


			-rpg-

∂17-Mar-89  1246	X3J13-mailer 	Issue: PACKAGE-FUNCTION-CONSISTENCY, V.3 
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89  12:45:23 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Fri, 17 Mar 89 14:55:05 EST
Date: Fri, 17 Mar 89 14:46 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Issue: PACKAGE-FUNCTION-CONSISTENCY, V.3
To: masinter.pa@xerox.com
Cc: x3J13@sail.stanford.edu
In-Reply-To: <890317-102812-1247@Xerox>
Message-Id: <19890317194641.7.BARMAR@OCCAM.THINK.COM>

    Date: 17 Mar 89 10:25 PST
    From: masinter.pa@xerox.com

    Proposal (PACKAGE-FUNCTION-CONSISTENCY:MORE-PERMISSIVE):

      Clarify that the functions PACKAGE-NAME, PACKAGE-NICKNAMES, 
      PACKAGE-USE-LIST, and PACKAGE-USED-BY-LIST are (at least conceptually)
      accessors to package data structures and permit only package objects
      as arguments.

    ...

    In addition, require that PACKAGE-NAME, PACKAGE-NICKNAMES, 
    PACKAGE-USE-LIST, and PACKAGE-USED-BY-LIST  to accept names,
    too.

You can't have it both ways!  Also, the grammar of the second one could
use improving.

                                                barmar

∂17-Mar-89  1257	X3J13-mailer 	Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89  12:57:27 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Fri, 17 Mar 89 15:52:50 EST
Date: Fri, 17 Mar 89 15:53 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
To: Jon L White <jonl@lucid.com>
Cc: cl-cleanup@sail.stanford.edu, X3J13@sail.stanford.edu
In-Reply-To: <8903160732.AA11607@bhopal>
Message-Id: <19890317205329.0.BARMAR@OCCAM.THINK.COM>

What happens in implementations that allow all arrays to be adjusted?
If you require that (typep x 'simple-array) implies (not
(adjustable-array-p x)), I see two possible resolutions: 1) such
implementations are not conforming; 2) the type SIMPLE-ARRAY is empty.
I find (1) distasteful, because non-adjustable arrays and the
SIMPLE-ARRAY type exist solely for the benefit of implementations that
need them, and this would require support of these concepts in
implementations that don't derive any benefit from them.  I think (2)
makes the SIMPLE-ARRAY type pretty useless, since a portable program
can't expect anything to be of this type (FIXNUM had this problem until
we fixed it in Hawaii).

                                                barmar

∂17-Mar-89  1251	CL-Compiler-mailer 	**DRAFT** issue SYNTACTIC-ENVIRONMENT-ACCESS (version 4)    
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 17 Mar 89  12:51:13 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 559802; Fri 17-Mar-89 15:48:20 EST
Date: Fri, 17 Mar 89 15:48 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** issue SYNTACTIC-ENVIRONMENT-ACCESS (version 4)
To: Eric Benson <eb@lucid.com>
cc: cl-compiler@sail.stanford.edu, x3j13@sail.stanford.edu
In-Reply-To: <8903152040.AA00297@blacksox>
Message-ID: <19890317204812.5.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Wed, 15 Mar 89 12:40:06 PST
    From: Eric Benson <eb@lucid.com>

       Date: Tue, 14 Mar 89 18:41 EST
       From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>

       The :MACRO argument to AUGMENT-ENVIRONMENT shouldn't look like the CADR
       of a MACROLET special form, instead it should be a list of lists (name
       function).

    A small point: Shouldn't this be an a-list of the form
    (name . function) instead of a list of lists?

Oh, I keep forgetting that some people have to worry about the efficiency
of conses versus lists.  I don't care which it is.

∂17-Mar-89  1254	CL-Cleanup-mailer 	Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 17 Mar 89  12:54:39 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 559814; Fri 17-Mar-89 15:51:33 EST
Date: Fri, 17 Mar 89 15:51 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
To: Jon L White <jonl@lucid.com>
cc: cl-cleanup@sail.stanford.edu, X3J13@Sail.stanford.edu
In-Reply-To: <8903160732.AA11607@bhopal>
Message-ID: <19890317205125.6.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Wed, 15 Mar 89 23:32:47 PST
    From: Jon L White <jonl@lucid.com>

    Although I haven't had time to join the overly-lengthy discussion on this
    matter,  I did point out one particularly confusing direction -- that this
    proposal to "fix" the function ADJUST-ARRAY has become a proposal to alter 
    the semantics of the type SIMPLE-ARRAY.

Adding the discussion of SIMPLE-ARRAY was at *+*YOUR*+* request, JonL.
There is !!NO!! change to the semantics, as I thought you had agreed in
the last message you sent on the topic.  If now you're taking that back
and saying that you still think what this proposal says is a change to
the semantics, okay, but I have yet to figure out why you think that or
what you think is changed.

∂17-Mar-89  1316	X3J13-mailer 	Issue DYNAMIC-EXTENT: a remark 
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89  13:15:31 PST
Received: from fafnir.think.com by Think.COM; Fri, 17 Mar 89 14:55:24 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Fri, 17 Mar 89 14:54:21 EST
Received: by verdi.think.com; Fri, 17 Mar 89 14:51:09 EST
Date: Fri, 17 Mar 89 14:51:09 EST
From: Guy Steele <gls@Think.COM>
Message-Id: <8903171951.AA09006@verdi.think.com>
To: Moon@stony-brook.scrc.symbolics.com
Cc: gls@Think.COM, masinter.pa@xerox.com, X3J13@sail.stanford.edu
In-Reply-To: David A. Moon's message of Thu, 16 Mar 89 17:15 EST <19890316221519.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: Issue DYNAMIC-EXTENT: a remark

   Date: Thu, 16 Mar 89 17:15 EST
   From: David A. Moon <Moon@stony-brook.scrc.symbolics.com>
   Line-Fold: No

       Date: Thu, 16 Mar 89 15:34:53 EST
       From: Guy Steele <gls@Think.COM>

	     A "proper
	     part" of an object A is any object that is accessible at the beginning
	     of the scope of the declaration -only- by applying a function to A or to
		↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
	     a "proper part" of A.  This means that any objects freshly allocated
	     during the construction of the initial value of the declared variable,
	     and not "saved" during the construction of that value, are "proper
	     parts" and can be allocated on a stack.

       I believe that the words indicated above should be replaced by
       "the extent of the binding for which the delaration was made".

   That would change the meaning, since the declaration might not be attached
   to a binding.

I am not certain that I understand the meaningful uses of this declaration
in cases where it is not attached to a binding.

       The reference appears to be to a point in time.  Scopes are in space;
       the beginning of a scope is a character position in the text (or
       something like that).  Extents are in time.  Is this what you meant?

   You're right that there is something wrong with this wording.  How about
   if it said "at the beginning of execution of the forms in the scope of
   the declaration"?  Do declarations have extents?  If so, could it say
   "at the beginning of the extent of the declaration"?

I think you have to speak in terms of run-time instantiations
of executable code.  Not sure.
--Guy

∂17-Mar-89  1356	CL-Compiler-mailer 	**DRAFT** issue SYNTACTIC-ENVIRONMENT-ACCESS (version 4)    
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89  13:54:27 PST
Received: from fafnir.think.com by Think.COM; Fri, 17 Mar 89 16:48:54 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Fri, 17 Mar 89 16:50:04 EST
Received: by verdi.think.com; Fri, 17 Mar 89 16:46:51 EST
Date: Fri, 17 Mar 89 16:46:51 EST
From: Guy Steele <gls@Think.COM>
Message-Id: <8903172146.AA09535@verdi.think.com>
To: Moon@stony-brook.scrc.symbolics.com
Cc: eb@lucid.com, cl-compiler@sail.stanford.edu, x3j13@sail.stanford.edu
In-Reply-To: David A. Moon's message of Fri, 17 Mar 89 15:48 EST <19890317204812.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: **DRAFT** issue SYNTACTIC-ENVIRONMENT-ACCESS (version 4)

   Date: Fri, 17 Mar 89 15:48 EST
   From: David A. Moon <Moon@stony-brook.scrc.symbolics.com>

       Date: Wed, 15 Mar 89 12:40:06 PST
       From: Eric Benson <eb@lucid.com>

	  Date: Tue, 14 Mar 89 18:41 EST
	  From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>

	  The :MACRO argument to AUGMENT-ENVIRONMENT shouldn't look like the CADR
	  of a MACROLET special form, instead it should be a list of lists (name
	  function).

       A small point: Shouldn't this be an a-list of the form
       (name . function) instead of a list of lists?

   Oh, I keep forgetting that some people have to worry about the efficiency
   of conses versus lists.  I don't care which it is.

Well, don't forget PAIRLIS and ACONS, which make the CONS format
a little easier to use than the LIST format.

[Voice 1: AAAAHHHHH!!!  No!!! Not FORMAT!!!]

Calm down; I meant it generically.  Make that "organization".

[Voice 2:  AUUGUGGHH!  Not generics!]

--Guy


∂17-Mar-89  1426	X3J13-mailer 	CLTL II    
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89  14:24:50 PST
Received: from fafnir.think.com by Think.COM; Fri, 17 Mar 89 17:20:09 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Fri, 17 Mar 89 17:21:19 EST
Received: by verdi.think.com; Fri, 17 Mar 89 17:18:06 EST
Date: Fri, 17 Mar 89 17:18:06 EST
From: Guy Steele <gls@Think.COM>
Message-Id: <8903172218.AA09852@verdi.think.com>
To: x3j13@sail.stanford.edu
Cc: gls@Think.COM
Subject: CLTL II

I have mailed copies of my current working draft of "CLTL II" to
nearly everyone on the X3J13 mailing list (defined to be the set of
mailing labels Bob Mathis sent me).  Those of you in the US can expect
to receive them on Monday or Tuesday via UPS, except for the three of
you whose address is a P.O. Box, in which case you are at the mercy of
Priority SnailMail.  I don't know how long it will take for
international delivery.

To keep the costs down, where two persons were at the same address or
organization, I sent only one copy; for three or more I generally sent
two copies.  (In all I sent out 70 copies, at about 30 bucks each
including shipping.)

KMP points out that it would be a serious mistake for everyone to drop
everything and start reading this draft, and I agree.  It is more
important to prepare for the upcoming meeting.  Furthermore, I would
hate to see anyone burn out reading this less-than-authoritative draft
of a less-than-authoritative book and then not have the energy to give
the draft standard a careful reading as well.

You don't *have* to read it at all.  If you don't have the time, then
use it as a doorstop, keep it as a souvenir, or give it to someone
like a graduate student.

I will be grateful for any feedback I can get, of course.  I recommend
that you pay the most attention to my paraphrasing of and commentary
on issues with which you have been particularly involved, to make sure
I didn't goof it up.  There is an index to the issues in the back that
may be helpful.

Some of the new material has nothing whatsoever to do with X3J13.
You may wish to check out the I/O and Numbers chapters, for example.

Digital Press will have a copy editor reading it for grammar and
punctuation, and I will be reading it carefully, so if your time
is limited you probably should concentrate on the conceptual level.
I am especially interested in feedback of the form "You're going about
this all wrong.  Here's what you should do..."

Don't worry at all about fonts, spacing, or number of pages.  What I
shipped to you today is merely 300-dots-per-inch draft quality with
the wrong fonts.  I am meeting next week with the book designer at
Digital Press and we are going to work out what to do.  I also have a
list of changes to make to my TeX macros that will systematically
improve the spacing and page break decisions.

--Guy

∂17-Mar-89  1541	CL-Cleanup-mailer 	Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89  15:40:34 PST
Received: from fafnir.think.com by Think.COM; Fri, 17 Mar 89 16:23:16 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Fri, 17 Mar 89 16:24:05 EST
Received: by verdi.think.com; Fri, 17 Mar 89 16:20:53 EST
Date: Fri, 17 Mar 89 16:20:53 EST
From: Guy Steele <gls@Think.COM>
Message-Id: <8903172120.AA09400@verdi.think.com>
To: jonl@lucid.com
Cc: cl-cleanup@sail.stanford.edu, X3J13@sail.stanford.edu
In-Reply-To: Jon L White's message of Wed, 15 Mar 89 23:32:47 PST <8903160732.AA11607@bhopal>
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)

   Date: Wed, 15 Mar 89 23:32:47 PST
   From: Jon L White <jonl@lucid.com>
   ...
   Also, I note that all of the discussion on the Cl-cleanup list was by
   persons other than the half-dozen or so maintainers of "stock hardware"
   compilers.  I personally spoke with three others (not including myself)
   at Hawaii, and we all have identical requirements for the type SIMPLE-ARRAY,
   and identical resolve that it must not be changed.  Our compilers will
   continue to offer this C-level optimization capability; the only 
   question is whether or not the CL1989 Standard will be cognizant of it.

I am very concerned about the stock hardware, but also very confused.
I understand that the stock-hardware implementors adamantly oppose
the proposed change, but I still have not seen a single convincing
example of why the proposed change would prevent them from accomplishing
the desired optimizations or why the proposed change would defeat
portability.  I acknowledge that JonL has provided an example or two,
but I have not found them convincing.  So either these examples are
wrong, or I am badly wedged; in either case I need further explanation.
--Guy

∂17-Mar-89  1555	X3J13-mailer 	Re: Issue: COERCE-INCOMPLETE (Version 3) 
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89  15:55:11 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Fri, 17 Mar 89 18:48:21 EST
Date: Fri, 17 Mar 89 18:48 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Re: Issue: COERCE-INCOMPLETE (Version 3)
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
Cc: Kent M Pitman <KMP@stony-brook.scrc.symbolics.com>, masinter.pa@xerox.com,
        x3j13@sail.stanford.edu
In-Reply-To: <8903171654.AA06800@defun.utah.edu>
Message-Id: <19890317234839.3.BARMAR@OCCAM.THINK.COM>

    Date: Fri, 17 Mar 89 09:54:35 MST
    From: sandra%defun@cs.utah.edu (Sandra J Loosemore)

    Personally, I don't think this is a valid argument for not getting rid
    of COERCE, since it is easy to coerce a lambda expression to a function
    using (EVAL `(FUNCTION ,x)).

I disagree.  Many of us would not have voted in favor of FUNCTION-TYPE
without the coercion.  We wanted either a specific function or the
extension to COERCE.  We specifically did not feel that the above idiom
should be used in any actual code; it merely serves as a good way of
describing the value that the coercion returns.

I'll go along with COERCE-INCOMPLETE:DEPRECATE if it is amended to
include a new function that coerces a lambda expression, symbol, or
function to a function.  I'll even suggest a name: MAKE-FUNCTION
(unfortunately, FUNCTION is taken, so it can't follow the precedent of
naming a function that coerces to type T just T).

                                                barmar

∂17-Mar-89  1600	X3J13-mailer 	Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 17 Mar 89  16:00:33 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA02088g; Fri, 17 Mar 89 15:53:13 PST
Received: by bhopal id AA19366g; Fri, 17 Mar 89 15:55:29 PST
Date: Fri, 17 Mar 89 15:55:29 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8903172355.AA19366@bhopal>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
Cc: cl-cleanup@sail.stanford.edu, X3J13@Sail.stanford.edu
In-Reply-To: David A. Moon's message of Fri, 17 Mar 89 15:51 EST <19890317205125.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)

re: Adding the discussion of SIMPLE-ARRAY was at *+*YOUR*+* request, JonL.

Sorry, Dave, I only ever made a request to add precisely the one statement
that you have already now added -- that the proposal *does not* alter
the CLtL semantics of SIMPLE-ARRAY.  What I critiqued were statements
of the proposal that under reasonable interpretation could be taken to
mean that the CLtL p.28 definition of SIMPLE-ARRAY is being abrogated.

At any rate, thanks for the one-line addition.


-- JonL --

∂17-Mar-89  1613	X3J13-mailer 	Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 17 Mar 89  16:13:52 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA02119g; Fri, 17 Mar 89 16:06:33 PST
Received: by bhopal id AA19436g; Fri, 17 Mar 89 16:08:50 PST
Date: Fri, 17 Mar 89 16:08:50 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8903180008.AA19436@bhopal>
To: barmar@Think.COM
Cc: cl-cleanup@sail.stanford.edu, X3J13@sail.stanford.edu
In-Reply-To: Barry Margolin's message of Fri, 17 Mar 89 15:53 EST <19890317205329.0.BARMAR@OCCAM.THINK.COM>
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)

re: I find (1) distasteful, because non-adjustable arrays and the
    SIMPLE-ARRAY type exist solely for the benefit of implementations that
    need them, and this would require support of these concepts in
    implementations that don't derive any benefit from them.  

Barry, SIMPLE-ARRAY is certainly not the only concept in CLtL that exists
"solely for the benefit of implementations that [can really use it]".  I
know that numerous array capabilities are present but not very useful
in Lucid Common Lisp primarily for compatiblity with Lisp Machine stuff.

That's the price to pay for portability.  It just may be that we will have 
to confess that we didn't succeed at portability in some areas of CL.


-- JonL --

∂17-Mar-89  1612	X3J13-mailer 	Re: Issue: COERCE-INCOMPLETE (Version 3) 
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89  16:12:34 PST
Received: from Salvador.ms by ArpaGateway.ms ; 17 MAR 89 16:02:36 PST
Date: 17 Mar 89 15:57 PST
From: masinter.pa@Xerox.COM
Subject: Re: Issue: COERCE-INCOMPLETE (Version 3)
In-reply-to: masinter.pa's message of 17 Mar 89 08:47 PST
To: masinter.pa@Xerox.COM
cc: Barry Margolin <barmar@Think.COM>, x3j13@sail.stanford.edu
Message-ID: <890317-160236-2538@Xerox>

Sorry, I was confused when I sent that message. Yes, COERCE coerces lambda
expressions to functions. No, APPLY and FUNCALL do not (are not required
to)
do such coercions.


∂17-Mar-89  1623	X3J13-mailer 	Issue: PACKAGE-FUNCTION-CONSISTENCY, V.3 
Received: from YUKON.SCRC.Symbolics.COM (SCRC-YUKON.ARPA) by SAIL.Stanford.EDU with TCP; 17 Mar 89  16:23:09 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by YUKON.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 439582; Fri 17-Mar-89 19:22:26 EST
Date: Fri, 17 Mar 89 19:20 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: PACKAGE-FUNCTION-CONSISTENCY, V.3
To: masinter.pa@Xerox.COM
cc: x3J13@sail.stanford.edu
In-Reply-To: <890317-102812-1247@Xerox>
Message-ID: <19890318002018.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

    Date: 17 Mar 89 10:25 PST
    From: masinter.pa@Xerox.COM

    The notes from the January meeting said Accepted MORE-PERMISSIVE (v2),
    as amended. Amendments made at the meeting added DELETE-PACKAGE and
     DEFPACKAGE  to the list of functions and removed the paragraph beginning
    with the words "If IN-PACKAGE...".

    I can't figure out where a package name *isn't* allowed in DEFPACKAGE
    or where a package object would make sense. Are the notes incorrect,
    or were we just to hasty?

It wasn't my amendment, but I don't see why a package object should be 
disallowed in any position in DEFPACKAGE other than the name or nickname
of the package being defined.  I'll send a version that I think is correct
to CL-Cleanup and if no one disagrees it can be mailed to X3J13 to
supersede this one.

∂17-Mar-89  1656	X3J13-mailer 	Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 17 Mar 89  16:56:32 PST
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by Think.COM; Fri, 17 Mar 89 19:52:28 EST
Date: Fri, 17 Mar 89 19:53 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 8)
To: Jon L White <jonl@lucid.com>
Cc: cl-cleanup@sail.stanford.edu, X3J13@sail.stanford.edu
In-Reply-To: <8903180008.AA19436@bhopal>
Message-Id: <19890318005322.4.BARMAR@OCCAM.THINK.COM>

    Date: Fri, 17 Mar 89 16:08:50 PST
    From: Jon L White <jonl@lucid.com>

    re: I find (1) distasteful, because non-adjustable arrays and the
	SIMPLE-ARRAY type exist solely for the benefit of implementations that
	need them, and this would require support of these concepts in
	implementations that don't derive any benefit from them.  

    Barry, SIMPLE-ARRAY is certainly not the only concept in CLtL that exists
    "solely for the benefit of implementations that [can really use it]".  I
    know that numerous array capabilities are present but not very useful
    in Lucid Common Lisp primarily for compatiblity with Lisp Machine stuff.

    That's the price to pay for portability.  It just may be that we will have 
    to confess that we didn't succeed at portability in some areas of CL.

    -- JonL --

The general rule has been that implementations that don't need (or don't
provide) these types of optimizations can safely ignore the language
features that support them.  Some implementations can optimize array
access by knowing that the array can't be adjusted; other
implementations should not be required to remember this information if
they don't need it.  Quoting from CLtL: "features that are useful only
on certain 'ordinary' or 'commercial' processors are avoided or made
optional."

Any feature of the language that provides access to facets of the
implementation allows somewhat non-portable code, meaning that it is
possible to write conforming code that produces different results in
different implementations.  The simple program (PROGN
MOST-POSITIVE-FIXNUM) is conforming but produces many different results,
although the program (TYPEP MOST-POSITIVE-FIXNUM 'FIXNUM) is guaranteed
to return T in all conforming implementations.  To paraphrase Moon, it
would be wonderful if all conforming programs were portable, but that's
unrealistic (it would be like expecting the grammar of a language to
only permit sensible sentences to be formed -- I suspect Godel's
Incompleteness Theorem comes into play here, pointing out that if the
grammar allows you to say everything you'd want to say, it must also
include some nonsense).  The best I think we can do is provide enough
tools in the language to allow programs to detect implementation
differences and deal with them.

One thing that would help me is if you would post an example of code
that you feel is affected by this issue.  I think you described such
things to me in words at the last meeting, but I (like GLS) am having a
hard time figuring out precisely what the problem is (I had the same
difficulty with the FIXNUM stuff that started the moby flame session in
the car on the way to the Japanese restaurant).

                                                barmar

∂17-Mar-89  1758	X3J13-mailer 	too much mail!  
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 17 Mar 89  17:58:23 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA21950; Fri, 17 Mar 89 18:56:10 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA07465; Fri, 17 Mar 89 18:56:08 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903180156.AA07465@defun.utah.edu>
Date: Fri, 17 Mar 89 18:56:07 MST
Subject: too much mail!
To: x3j13@sail.stanford.edu

Hey folks, I have a request.  If you want to discuss an issue from one
of the subcommittees that was mailed to X3J13, please try to confine
the discussion to the appropriate subcommittee mailing list (or even
private mail to the person you're arguing with) instead of CC'ing all
of X3J13.  Some of us have been getting hundreds of mail messages a
day and I (at least) don't have the time to follow all of the detailed
arguments on issues from other subcommittees anyway.  I'd like to know
what the resolution of the problems is, but I don't really need to get
a blow-by-blow account in the meantime. 

You will be getting such a summary (and some revised proposals) from
cl-compiler around the end of next week, by the way.

-Sandra
-------

∂17-Mar-89  2051	X3J13-mailer 	March meeting issues and sections   
Received: from decwrl.dec.com by SAIL.Stanford.EDU with TCP; 17 Mar 89  20:51:38 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA16495; Fri, 17 Mar 89 10:21:57 PST
Received: by decwrl.dec.com (5.54.5/4.7.34)
	id AA16495; Fri, 17 Mar 89 10:21:57 PST
Message-Id: <8903171821.AA16495@decwrl.dec.com>
Received: by decwrl.dec.com (5.54.5/4.7.34)
	for skona%csilvax@hub.ucsb.edu; id AA16495; Fri, 17 Mar 89 10:21:57 PST
From: chapman%aitg.DEC@decwrl.dec.com
Date: 17 Mar 89 13:00
To: x3j13@sail.stanford.edu, skona%csilvax@hub.ucsb.edu
Subject: March meeting issues and sections

Dear Members:

The issues and sections of the standard named below have been
mailed to the X3J13 mailing list electronically and by hardcopy.
Also, the sections are available in files named march-1.dvi (chapter 1),
march-2.dvi (sections 2.1 and 2.2), march-5.dvi (chapter5), and
march-27-ballot.dvi (all the above-listed sections). Those files are
on hudson.dec.com, as usual, and the sources are there. 
These issues and sections will come to vote on March 30
during the X3J13 meeting. 

An affirmative vote on a section of the standard means that you 
agree with the contents of the section except possibly the following:

 Indentation of examples.
 Spelling and other typos.
 Figure placement and design.
 The physical presence of issue markers (these will be removed in
 the final draft); the issue markers sometimes change the indentation.


In addition, sections of the standard that could be modified by issues
passed by X3J13 that haven't been included up to this point, or have
been incorrectly included or under-included, will change even after
an affirmative vote on the section.

You are seeing two items again that appeared on the letter ballot:
ERROR-TERMINOLOGY, and Section 1.8. These were significantly changed
as a result of comments and will therefore require reviewing and
revoting.

On the front cover of each chapter that is part of this mailing (chapters 1, 2,
and 5) is a list headed by Reviewed by:. The people on this list
have simply READ and COMMENTED ON the attached sections. The appearance
of their names on the list is not an indication
of their endorsement, although they may in fact endorse the section they
reviewed.

Following is a summary of each issue and section's review history:

ERROR-TERMINOLOGY -- This issue was last revised by RPG, Moon, and
Pitman, and now they seem to be satisfied with the wording. This proposal is
directly reflected in Section 5.1.

CONFORMANCE-POSITION -- See the discussion section of this issue.
The issue is directly reflected in Section 1.5.

SUBSETTING-POSITION -- This issue has received general approval.

EXTENSIONS-POSITION -- Some would prefer we remain mute on this
issue, but the fact is that we have to provide some sort of definition
of an extension since we use the term in the ERROR-TERMINOLOGY proposal
and in the standard.

EXTRA-SYNTAX -- This issue has not received much comment until 
recently. A new revised version may be distributed at the meeting.

EXTRA-OPTIONAL-KEYWORD-ARGUMENTS -- Mixed reviews on this proposal.

EXTRA-RETURN-VALUES -- Not much discussion on this proposal although
it appears to be generally accepted. (Version 3, that is)

UNSPECIFIED-DATATYPES -- This proposal seems to be generally opposed.

UNSOLICITED-MESSAGES -- This issue has not received much comment
until recently. A revised version may be necessary.

MACRO-AS-FUNCTION -- Moon suggests that we just change the two
macros in question to functions (and skip the proposal?).

Sections 1.1-1.7 -- Some of these sections depend on the passage
of the previously-listed proposals. These sections have been reviewed
by numerous people and their comments have been included.
In addition, some suggestions for moving some of these sections
to an appendix are being entertained. That is covered in the TOC
issue which may undergo slight amendment at the meeting.

Sections 2.1-2.2 -- These sections have also been reviewed by
numerous people, and comments were included. The main unresolved
issues with section 2.2 seem to be as follows:
 Lack of integration with CLOS and the Condition System.
 Lack of a good definition of the type function.
These issues will most likely be resolved via clean-up proposals.

Sections 5.1-5.4 -- Section 5.1 is a rewrite of the concepts
part of the Condition System document approved by X3J13. It was reviewed in
detail by KMP, and also by Sandra Loosemore. The other sections were
reviewed by numerous people. 

Section 1.8 -- This section was sent out with the letter ballot.
Although the section was intended to be non-detailed, it was apparently 
much too vague to make it useful. It has been made slightly more detailed,
and whether or not it is at a suitable level will be decided by you.
A suggestion was made to move this section to an appendix.


If you need electronic copies of any of the issues, please let me know
(although they will be coming to you in hardcopy soon). If you have
any trouble accessing the standard sections, there are other ways 
besides FTP and hardcopy for you to get the standard. If I don't know
you're having trouble, though, I can't help you resolve the problem.

Thanks in advance for all your review time so far. Your comments and
suggestions are immensely useful.

kathy chapman

∂17-Mar-89  2110	X3J13-mailer 	Issue: EXTRA-RETURN-VALUES (version 3)   
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 17 Mar 89  21:10:01 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 560236; Sat 18-Mar-89 00:07:10 EST
Date: Sat, 18 Mar 89 00:06 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: EXTRA-RETURN-VALUES (version 3)
To: chapman%aitg.DEC@decwrl.dec.com
cc: x3j13@sail.stanford.edu
In-Reply-To: <8903160834.AA18011@decwrl.dec.com>
Message-ID: <19890318050654.7.MOON@EUPHRATES.SCRC.Symbolics.COM>

I would support this if it were amended with a list of functions
that are explicitly allowed to have additional return values.
As a suggested rough cut at such a list, how about all the functions
described in chapters 16, 21, 22, 23, 24, and 25 of CLtL?  These are
the functions that I would call "environment" rather than "language".

∂17-Mar-89  2304	X3J13-mailer 	Issue: PACKAGE-FUNCTION-CONSISTENCY (version 4)    
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 17 Mar 89  23:03:59 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 560302; Sat 18-Mar-89 02:00:54 EST
Date: Sat, 18 Mar 89 02:00 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: PACKAGE-FUNCTION-CONSISTENCY (version 4)
To: X3J13@sail.stanford.edu
Message-ID: <19890318070046.4.MOON@EUPHRATES.SCRC.Symbolics.COM>

This is a correction to some wording problems and inconsistencies
in version 3 that was mailed out yesterday.

!
Issue:        PACKAGE-FUNCTION-CONSISTENCY
References:   11.7 Package System Functions and Variables (pp182-188)
Category:     CLARIFICATION/CHANGE
Edit history: 21-Oct-88, Version 1 by Pitman
		12-Jan-89, Version 2 by Masinter (add MORE-PERMISSIVE option)
		17-Mar-89, Version 3, by Masinter, MORE-PERMISSIVE as
			amended & adopted at Jan 89 X3j13
		17-Mar-89, Version 4, by Moon, correct amended wording

Problem Description:

  CLtL is vague about whether either or both of package or package name
  are permissible in some cases.

Proposal (PACKAGE-FUNCTION-CONSISTENCY:MORE-PERMISSIVE):

  Clarify that it is permissible to pass either a package object
  or a package name (symbol or string) in the following situations:
    - the :USE argument to MAKE-PACKAGE or IN-PACKAGE
    - the first argument to IN-PACKAGE, FIND-PACKAGE, RENAME-PACKAGE
			or DELETE-PACKAGE
    - the second argument to INTERN, FIND-SYMBOL, UNINTERN
    - the second argument to EXPORT, UNEXPORT, IMPORT,
      SHADOWING-IMPORT, and SHADOW
    - the first argument (or a member of the list which is the first
      argument) to USE-PACKAGE or UNUSE-PACKAGE.
    - all package-name arguments in DEFPACKAGE except for the name and
      nicknames of the package being defined.
    - the first argument to PACKAGE-NAME, PACKAGE-NICKNAMES, 
      PACKAGE-USE-LIST, or PACKAGE-USED-BY-LIST
    - the PACKAGE argument to DO-SYMBOLS.
    - the PACKAGE argument to DO-EXTERNAL-SYMBOLS.
    - the PACKAGE argument to DO-ALL-SYMBOLS.

  If FIND-PACKAGE is given a package object as an argument, it simply
  returns it.

  Clarify that the function MAKE-PACKAGE permits only a package name
  as an argument since it does not make sense to create an existing
  package.

  Clarify that package nicknames must always be expressed as package
  names (symbols or strings) and may never be actual package objects.

  In the list above, IN-PACKAGE may be changed to SELECT-PACKAGE
  if IN-PACKAGE-FUNCTIONALITY:NEW-MACRO passes.

Examples:

  (INTERN "FOO" "KEYWORD") => :FOO

  (DEFVAR *FOO-PACKAGE* (MAKE-PACKAGE "FOO"))
  (RENAME-PACKAGE "FOO" "FOO0")
  (PACKAGE-NAME *FOO-PACKAGE*) => "FOO0"


  (PACKAGE-NAME "SYS") might return "SYSTEM".

Rationale:

   This makes things more consistent.
   It also adds a generally useful capability.


Current Practice:

  Symbolics Genera & Lucid permit strings as package names.
  Symbolics Cloe does not permit strings as package names.
  In Lucid FIND-PACKAGE and IN-PACKAGE require names.

Cost to Implementors:

  Small.

Cost to Users:

  None. This change is upward compatible.

Cost of Non-Adoption:

  Implementations would continue to vary gratuitously, leaving a potential
  for portability problems.

Benefits:

  The cost of non-adoption is avoided.

Aesthetics:

  This makes things more regular, and so presumably more aesthetic.

Discussion:

  Pitman ran across this problem while trying to port Macsyma to various
  implementations. Discussion with other maintainers of portable programs
  shows this is a common source of aggravation in portable code.

  It would be possible to say that MAKE-PACKAGE took package objects as
  arguments and just returned that package. That might have limited
  usefulness on rare occasions, but mostly seemed too far out in left
  field to bother suggesting it.

∂18-Mar-89  0137	X3J13-mailer 	The Cleanup Issue Status List  
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 18 Mar 89  01:37:09 PST
Received: from Semillon.ms by ArpaGateway.ms ; 18 MAR 89 01:34:10 PST
Date: 18 Mar 89 01:33 PST
From: masinter.pa@Xerox.COM
to: X3J13@sail.stanford.edu
Subject: The Cleanup Issue Status List
Message-ID: <890318-013410-3635@Xerox>


This is the complete list of Cleanup issues that are either:

passed: passed at *any* previous meeting, including Jan 89

pending: have been distributed for the March meeting

in progress: might possibly be distributed for the March meeting,
	or that I think are worth pursuing.

Of course, some more might come up or be revived.

I think I have updated versions of all pending and passed
issues stored on arisia.xerox.com under the
	clcleanup/pending
	clcleanup/passed

directories respectively.

I'm pretty much unavailable (travelling, etc.) until the meeting.
I'll try to read my mail while on the road, but
it will be difficult to handle the quantity we've
seen in the last week.


Codes:

! released for Jan 89 meeting
+ passed
* need new version


!*: released, but I know we'll need a new version
+*: passed, but need to reconsider
!*: passed, but need a new version to reconsider

!

+ ADJUST-ARRAY-DISPLACEMENT
Version 4, 23-Nov-87
Status: passed, 1988

+ ADJUST-ARRAY-FILL-POINTER
 Version 1, 15-MAR-88
Status: passed, 1988

! ADJUST-ARRAY-NOT-ADJUSTABLE
Synopsis: ADJUST-ARRAY on array made with :ADJUSTABLE NIL: "an error"?
Version 4, 11-Jan-89, Released 12-Jan-89
Status: Accepted with amendments Jan 89 X3J13
Comments:  amendment had wording problem.
Version 8, 11-Mar-89, Released 15-Mar-89
Status: ready for vote 

+ APPLYHOOK-ENVIRONMENT
Synopsis: remove (useless) env argument to applyhook
Version 2, 10-Jan-89, Released 10-Jan-89
Status: Passed Jan-89 X3J13

+ AREF-1D
14-NOV-87, Version 7
Status: Passed, 1988?

+ ARGUMENTS-UNDERSPECIFIED
Synopsis: Clarify various ranges missing from CLtL
Version 4, 21-Sep-88, Released 4 Dec 88
Status: Passed Jan 89 X3J13

+ ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS
Synopsis: What do array element-type declarations mean?
Version 9, 31-Oct-88, Released 5 Dec 88
Status: Passed Jan 89 X3J13

+ ASSOC-RASSOC-IF-KEY
Version 4, 23-NOV-87
Status: Passed, 1988?

! BREAK-ON-WARNINGS-OBSOLETE
Synopsis: deprecate *BREAK-ON-WARNINGS* because of *BREAK-ON-SIGNALS*
Version 1, 07-Mar-89, Released 15-Mar-89
Comment: leaves out a case
Status: ready for vote

! CLOS-CONDITIONS
Version 4, 10-Mar-89
Comments: define metaclass of conditions? 
Status: pending

+ CLOSE-CONSTRUCTED-STREAMS
Synopsis: What does it mean to CLOSE a constructed stream?
Version 2, 12-Jan-89, Released 12-Jan-89
Status: Proposal ARGUMENT-STREAM-ONLY passed Jan 89 X3J13

!+ CLOSED-STREAM-OPERATIONS
Synopsis: What operations are legal on closed streams?
Version 5, 5-Dec-88, released 5-Dec-88
Status: amended at meeting
Version 7, 14-Feb-89
Status: Passed, as amended, Jan 89 X3J13
Comment: amendment bad; reconsider version 5.
	say that INPUT-STREAM-P and OUTPUT-STREAM-P
	are undefined on closed streams?

! COERCE-INCOMPLETE
Synopsis: Extend COERCE
Version 3, 7-Mar-89, Released 14-Mar-89
Status: ready for voting

+ COLON-NUMBER
Synopsis:  :123 is an error
22-OCT-87, Version 1
Status: Passed, 1988?

+ COMPILER-WARNING-STREAM
Version 6, 5-JUN-87
Status: Passed, 1988?

+ COMPLEX-ATAN-BRANCH-CUT
Synopsis: tweak upper branch cut in ATAN formula
Version 1, 13-Dec-88, Released 10-Jan-89
Status: Passed Jan 89 X3J13

!* CONDITION-RESTARTS
Synopsis: can't know whether restart is associated with signalling
Version 1, 18-Jan-89, released 16-Mar-89
Comment: (proposed amendments)
Status: need new version

+ CONTAGION-ON-NUMERICAL-COMPARISONS
Version 1, 14-Sep-88, Released 6 Oct 88
Status: passed, Jan 89 X3J13

! COPY-SYMBOL-COPY-PLIST
Version 1, 10-Jan-89, released 16-Mar-89
Status: ready for vote

! COPY-SYMBOL-PRINT-NAME
Version 2, 15-Mar-89, released 16-Mar-89
Status: ready for vote

+ DATA-TYPES-HIERARCHY-UNDERSPECIFIED
4-SEP-88 Version 2
Status: Passed, 1988?

+ DECLARATION-SCOPE
Version 4, 15-Nov-88, Released 9-Dec-88
Status: NO-HOISTING passed Jan 89 X3J13

+ DECLARE-ARRAY-TYPE-ELEMENT-REFERENCES
Version 3, 13-Jan-89
Status: passed, Jan 89 X3J13

+ DECLARE-FUNCTION-AMBIGUITY
Version 4,  5-Dec-88, Released  5-Dec-88
Status: passed, Jan 89 X3J13

+ DECLARE-MACROS
5-FEB-88, Version 3
Status: Passed, 1988?

+ DECLARE-TYPE-FREE
Version 10, 12-Jan-89
Status: proposal LEXICAL passed Jan 89 X3J13

+ DECODE-UNIVERSAL-TIME-DAYLIGHT
Version 2, 30-Sep-88, Released 6 Oct 88
Status: Passed, Jan 89 x3j13

* DEFMACRO-LAMBDA-LIST
Version 2, 17-Mar-89
Status: ready for release?

+ DEFPACKAGE
Version 7, 2-Nov-88, Released 5 Dec 88
Comment: clarify "at variance" in editorial work?
Status: Passed, Jan 89 X3J13

+ DEFSTRUCT-CONSTRUCTOR-KEY-MIXTURE
Version 3, 8-Jan-89, Released 11-Jan-89
Status: Passed, Jan 89 X3J13

+ DEFSTRUCT-DEFAULT-VALUE-EVALUATION
Version 1, 5/13/88
Status: Passed, 1988

+ DEFSTRUCT-PRINT-FUNCTION-INHERITANCE
Version 3, 7 Dec 88, Released 12-Dec-88
Status: Passed, Jan 89 X3J13

+ DEFSTRUCT-REDEFINITION
Synopsis: what happens if you redefine a DEFSTRUCT?
Version 3, 6-Feb-89
Status: Passed (as amended) Jan 89 X3J13

+ DEFSTRUCT-SLOTS-CONSTRAINTS-NAME
Version 5, 12-Jan-89
Status: Passed, Jan 89 X3J13

+ DEFSTRUCT-SLOTS-CONSTRAINTS-NUMBER
Version 1, 5/13/88
Status: Passed, 1988

+ DEFVAR-DOCUMENTATION
23-NOV-87, Version 2
Status: Passed, 1988?

+ DEFVAR-INIT-TIME
29-MAR-87, Version 2
Status: Passed, 1988?

+ DEFVAR-INITIALIZATION
Version 4 5-JUN-87
Status: Passed, 1988?

+ DESCRIBE-INTERACTIVE
Version 4, 15-Nov-88, Released 7-Dec-88
Synopsis: can DESCRIBE ask user a question?
Status: Proposal NO passed Jan 89 X3J13

! DESCRIBE-UNDERSPECIFIED
Version 1, 10-Mar-89, Released 16-Mar-89
Synopsis: making DESCRIBE generic was wrong; fix
status: ready for vote

!* DESTRUCTURING-BIND
Version 2, 25-Jan-89, Released 16-Mar-89
Synopsis: add DESTRUCTURING-BIND macro
Status: might need new version before vote

+ DISASSEMBLE-SIDE-EFFECT
Version 3 1/21/88
Status: Passed, 1988

+ DO-SYMBOLS-DUPLICATES
Version 3 23-NOV-87
Status: Passed, 1988?

+ DOTTED-MACRO-FORMS
Version 3, 15-Nov-88, Released 7-Dec-88
Status: passed, Jan 89 X3J13

+ DRIBBLE-TECHNIQUE
14-FEB-88, Version 2
Status: Passed, 1988?

! DYNAMIC-EXTENT
Version 3, 11-Jan-89, released 16-Mar-89
Comments: still some holes
Status: ready for vote?

+ EQUAL-STRUCTURE
Version 6, 11-Jan-89, Released 12-Jan-89
Status: Passed with amendments
Version 7, 15-Mar-89
Status: Passed Jan 89 X3J13 as amended.

* EQUALP-GENERIC
Version 1, 28-Feb-89
Synopsis: make EQUALP generic function
Comments: Various problems being worked on
Status: ** NEED NEW VERSION ***

* ERROR-CHECKING-IN-NUMBERS-CHAPTER
Version 1, 6-Mar-89
Synopsis: define 'should signal', 'might signal' for number fns
Status: ** NEED NEW VERSION **

! ERROR-NOT-HANDLED
Version 1, 25-Sep-88, Released 6-Oct-88 and 14-Mar-89
Status: ready for vote

+ EVAL-OTHER
8-JUN-88, Version 2
Status: Passed, 1988?

! EXIT-EXTENT
Version 6,  8-Jan-89, distributed at Jan89 X3J13
Rereleased 16-Mar-89
Status: tabled Jan89; ready for vote

+ EXPT-RATIO
Version 3, 31-Oct-88, Released 7 Dec 88
Status: passed, Jan 89 X3J13

+ FIXNUM-NON-PORTABLE
Version 4, 7-Dec-88, Released 12-Dec-88
Version 6, 17-Mar-89, as amended
Status: Passed, Jan 89 X3J13, as amended

+ FLET-DECLARATIONS
Version 2, 2 FEB 88
Status: Passed, 1988?

+ FLET-IMPLICIT-BLOCK
Version 6 5-JUN-87
Status: Passed, 1988?

+ FORMAT-ATSIGN-COLON
Version 4 5-JUN-87
Status: Passed, 1988?

+ FORMAT-COLON-UPARROW-SCOPE
Version 3, 5 FEB 88
Status: Passed, 1988?

+ FORMAT-COMMA-INTERVAL
Version 2, 15-JUN-87
Status: Passed, 1988?

+ FORMAT-E-EXPONENT-SIGN
Version 2, 2 Oct 88, Released 6 Oct 88
Status: Passed, Jan 89 X3J13

+ FORMAT-OP-C
11-JUN-87, Version 5
Status: Passed, 1988?

* FORMAT-PLURALS
Synopsis: remove ~P, add ~:@[singular~;plural~]
Status: no proposal

+ FORMAT-PRETTY-PRINT
Version 7, 15 Dec 88, Released 7 Dec 88
Comments: passed, Jan 89 X3j13

+ FUNCTION-CALL-EVALUATION-ORDER
Version 1, 22-MAR-88
Status: Passed, 1988

! FUNCTION-COERCE-TIME
Synopsis: When does SYMBOL-FUNCTION happen in MAPCAR?
Version 2, 16-sep-88, Released 8-Oct-88
Re-released: 16-Mar-89
Status: ready for vote?

+ FUNCTION-COMPOSITION
Synopsis: Add new functions
Version 5, 10-Feb-89 
Status: Passed (as amended) Jan 89 X3J13
     maybe this was passed as amendment to TEST-NOT-IF-NOT instead

+ FUNCTION-DEFINITION
Version 3, 10-Feb-89
Status: Passed (as amended) Jan 89 X3J13

! FUNCTION-NAME
Comment: renaming of SETF-FUNCTION-VS-MACRO, SETF-PLACES
SETF-FUNCTION-VS-MACRO
 Version 3, 4-Nov-87, Released Nov 87
SETF-PLACES
 Version 1, 11-Nov-88, Released 9-Dec-88
FUNCTION-NAME
 Version 1, 27-Jan-89, Released 16-Mar-89
Status: ready for vote

+ FUNCTION-TYPE
Version 12, 4-SEP-88
Status: Passed, June 1988 X3J13, as amended

+ FUNCTION-TYPE-ARGUMENT-TYPE-SEMANTICS
Synopsis: Change semantics of argument types in function declarations
Version 3, 7-Dec-88, Released  12-Dec-88
Status: Passed, Jan 89 X3J13

+ FUNCTION-TYPE-KEY-NAME
Version 3, 13-FEB-88 
Status: Passed, 1988

+ FUNCTION-TYPE-REST-LIST-ELEMENT
Version 5, 14-Nov-88, Released 8-Dec-88
Status: Passed, Jan 89 X3J13

! GENSYM-NAME-STICKINESS
Synopsis: no side effects if optional arg supplied
Version 1, 14-Feb-89, Released 14-Mar-89
Status: comments
Version 2, 16-Mar-89
Status: ready for release? 

+ GET-MACRO-CHARACTER-READTABLE
Version 3, 11-Feb-89
Status: Passed (as amended) Jan 89 X3J13

+ GET-SETF-METHOD-ENVIRONMENT
Version 5 13-JUL-87
Status: Passed, 1988?

! HASH-TABLE-ACCESS
Synopsis: Add new accessors for hash-table properties
Version 1, 13-Sep-88 released 8-Oct-88
Version 2, 13 Oct 88, released 16-Mar-89
status: vote 

+ HASH-TABLE-PACKAGE-GENERATORS
Version 7, 8-Dec-88, Released 9-Dec-88
Comments: The test-package-iterator example has the values
 from the generator in  the wrong order.
Status: passed, Jan 89 X3J13

* HASH-TABLE-PRINTED-REPRESENTATION
Version 2, 8-Jun-88
Comments: Use #S(ARRAY ...), #S(HASH-TABLE...), #S(PATHNAME...)?
Status: need new proposal

+ HASH-TABLE-TESTS
Version 2, 8-Dec-88, Released 8 Dec 8 8
Status: passed Jan 89 X3J13

+ IEEE-ATAN-BRANCH-CUT
Version 2, 11-Jan-89, Released 11-Jan-89
Status: passed, Jan 89 X3J13

* IGNORE-VARIABLE
Synopsis: default (IGNORE IGNORE)
Version 1, 6-Feb-89

+ IMPORT-SETF-SYMBOL-PACKAGE
Version 5 ??-MAY-87
Status: Passed, 1988?

! IN-PACKAGE-FUNCTIONALITY
Version 4, 12-Dec-88, Released 12-Dec-88
Status: tabled
Version 8, 15-Mar-89, Released 15-Mar-89
Status: ready for vote

+ KEYWORD-ARGUMENT-NAME-PACKAGE
8-NOV-87, Version 8
Status: Passed, 1988?

+ LAST-N
12-MAR-88, Version 2
Status: Passed, 1988?

+ LCM-NO-ARGUMENTS
Version 1, 17 Oct 88, Released 8 Dec 88
Status: passed, Jan 89 X3J13

! LISP-PACKAGE-NAME
Synopsis: change LISP to COMMON-LISP to avoid CLtL confusion
Version 1, 22 Dec 88, Released 11-Jan-89
Status: tabled; version 1 still ready for vote

! LISP-SYMBOL-REDEFINITION
Version 5, 22-Nov-88, Released 8 Dec 88
Comments: Don't like (DEFVAR CAR ...) example
	14: Like simpler "Redefining any documented
  definition on a symbol in the LISP package -- such as variables, 
  functions, constants, properties and property-lists, etc -- is
  undefined, except for the explicitly allowed cases (e.g. dynamic
  binding of variables)."
Status: tabled; version 5 still ready for vote

! LOAD-OBJECTS
Synopsis: Provide a way to allow defstruct/defclass objects in compiled files
Version 3, 9-Mar-89, released 16-Mar-89
Status: ready for vote?

! LOAD-TRUENAME
Synopsis: Make default pathname for LOAD inside LOAD same?
Version 1, 13-Mar-89, Released 16-Mar-89
Status: ready for vote

! LOCALLY-TOP-LEVEL
Version 2, 16-Mar-89, released 17-Mar-89
Status: ready to vote

! LOOP-AND-DISCREPANCY
Version 1, 15-Mar-89, released 16-Mar-89
status: ready for vote

+ MACRO-FUNCTION-ENVIRONMENT
Version 2, 8-JUN-88
Status: Passed, 1988

* MACRO-SPECIAL-FORMS
Synopsis: macros => implementation-dependent special forms doesn't work
Status: *** NEED PROPOSAL SUBMITTED ****

+ MAKE-PACKAGE-USE-DEFAULT
Version 2, 8 Oct 88, Released 12-Dec-88
Version 3, 16-Mar-89
Status: Passed, Jan 89 X3J13 as amended 

! MAKE-STRING-FILL-POINTER
Synopsis: extend MAKE-STRING to take a fill-pointer?
Version 1, 20-Oct-88, released 16-Mar-89
Status: ready for vote

+ MAPPING-DESTRUCTIVE-INTERACTION
Version 2, 09-Jun-88, Released 8 Oct 88
Synopsis: [don't] define interaction of DELETE on MAPCAR'd list.
Status: passed, Jan 89 X3J13

+ NTH-VALUE
Version 4, 8-Dec-88, Released 8 Dec 88
Comment: amended to clarify when index out of range
Version 5, 17-Mar-89
Status: passed, as amended

+ PACKAGE-CLUTTER
Version 6, 12-Dec-88, Released 12-Dec-88
Comments: Accepted, with amendment
Version 7, 17-Mar-89
Status: Passed, Jan 89 X3J13, as amended

+ PACKAGE-DELETION
Version 5, 21 nov 88, Released 8 Dec 88
Comments: Minor glitches? Remove the description of "correctable" error to be signalled and
handled.
Status: passed, Jan 89 X3J13

!+ PACKAGE-FUNCTION-CONSISTENCY
Synopsis: allow strings for package arg everywhere uniformly
Version 2, 12-Jan-89, Released 12-Jan-89
Comment: Accepted MORE-PERMISSIVE with amendments
Version 3, 17-Mar-89, released 17-Mar-89
Status: vote to accept wording as intent of amendment

* PATHNAME-CANONICAL-TYPE
Synopsis: allow canonical :SOURCE-LISP to MAKE-PATHNAME;
	require PATHNAME-TYPE to return same?
Version 1, 07-Jul-88
Comments: only add the :TYPE :SOURCE-LISP, not PATHNAME-CANONICAL-TYPE?
Status: => "pathname" committee?

* PATHNAME-LOGICAL
Synopsis: add logical pathnames (pathnames for an imaginary portable
file system, which get translated by site-dependent translations into
physical pathnames on an actual file system)
Status: no proposal yet

* PATHNAME-PRINT-READ
Synopsis: Print pathnames like #P"asdf"?
Version 1, 21-Oct-88
Comments: Numerous, pro, con. Print like #S(pathname ...)?
Status: *** NEED NEW VERSION ***

+ PATHNAME-STREAM
Version 6 14-NOV-87
Status: Passed, 1988?

+ PATHNAME-SYMBOL
Version 5 5-FEB-88
Status: Passed, 1988?

* PATHNAME-SUBDIRECTORY-LIST
Synopsis: How to deal with subdirectory structures in pathname functions
Version 3, 29-Dec-88
Comments: typos and proposed simplifications
Status: *** NEED NEW VERSION ***

* PATHNAME-SYNTAX-ERROR-TIME
Synopsis: when are errors in pathnames detected?
Version 1, 7-Jul-88
Comments: various
Status: need new version? ==> ERRORS-IN-FILE-CHAPTERS?

+  PATHNAME-UNSPECIFIC-COMPONENT
Synopsis: More extensions to :UNSPECIFIC
Version 1, 29-Dec-88, Released 12-Jan-89
Version 2, 17-Mar-89
Status: Passed, Jan 89 X3j13, as amended

+ PEEK-CHAR-READ-CHAR-ECHO
Version 3, 8-Oct-88, Released 8 Oct 88
Synopsis:  PEEK-CHAR, READ-CHAR on streams made by MAKE-ECHO-STREAM
Status: Passed, Jan 89 X3J13

* PRETTY-PRINT-INTERFACE
Version 3, 15-Mar-89
Synopsis: standardize interface to prettyprinter
Status: Need new version

+ PRINC-CHARACTER
29-APR-87, Version 2
Status: Passed, 1988?

* PRINT-CIRCLE-SHARED
Synopsis: does *PRINT-CIRCLE* cause shared structure to print with #=?
Status: Not submitted yet ** NEED WRITEUP **

+ PRINT-CIRCLE-STRUCTURE
Version 3, 20 Sep 88, Released 8 Oct 88
Comments: Accepted, with amendment
Version 4, 17-Mar-89
Status: Passed, Jan 89 X3J13, as amended

! PROCLAIM-LEXICAL
Version 9, 8-Dec-88, Released 12-Dec-88
Synopsis: add LEXICAL proclaimation
Comments: lengthy mail; amendments at Jan meeting
Status: tabled, vote on version 9 (w/o amendments)

+ PUSH-EVALUATION-ORDER
Version 5, 25-NOV-87
Status: Passed, 1988?

+ RANGE-OF-COUNT-KEYWORDS
Version 3, 9-Oct-88, Released 14-Oct-88
Status: passed, Jan 89 X3J13

+ RANGE-OF-START-AND-END-PARAMETERS
Version 1, 14-Sep-88, Released 7 Oct 88
Status: passed, Jan 89 X3J13

* READ-CASE-SENSITIVITY
Synopsis: Allow readtables to be case sensitive
Comments: use function or keyword?
Status: need new version

* READ-DELIMITED-LIST-EOF
Synopsis: eof in read deliminted list signals an error
Status: awaiting submission

! REAL-NUMBER-TYPE
Synopsis: add REAL = (OR RATIONAL FLOAT) & range
Version 3, 13-Jan-89, released 16-Mar-89
Status: vote?

+ REDUCE-ARGUMENT-EXTRACTION
Version 3 13-FEB-88
Status: Passed, 1988?

!* REMF-DESTRUCTION-UNSPECIFIED
Synopsis: Specification of side-effect behavior in CL
Version 4, 29-Nov-88, Released 12-Jan-89
Status: straw vote in favor of this, BarMar will make amendments
Version 5, 15-Mar-89
Comment: needs a little work
Status: *** NEARLY READY -- NEED NEW VERSION ****

+ REQUIRE-PATHNAME-DEFAULTS
Version 6, 9 Dec 88, Released 09 Dec 88
Status: passed, Jan 89 X3j13

+ REST-LIST-ALLOCATION
Version 3, 12-Dec-88, Released 12-Dec-88
Status: proposal MAY-SHARE passed, Jan 89 X3J13

+ RETURN-VALUES-UNSPECIFIED
Version 6, 9 Dec 88, Released  9-Dec-88
Status: passed, Jan 89 X3J13

+ ROOM-DEFAULT-ARGUMENT
Version 1, 12-Sep-88, Released 8 Oct 88
Status: passed, Jan 89 X3J13

* SETF-MULTIPLE-STORE-VARIABLES
Synopsis: Allow multiple "places" in SETF stores
Version 1, 5-Dec-88
Status: *** NEED NEW VERSION ****

+ SETF-SUB-METHODS
Version 5, 12-Feb-88, Released 8 Oct 88
Synopsis: careful definition of order inside (SETF (GETF ...) ...) 
Status: passed, Jan 89 X3J13

+ SHADOW-ALREADY-PRESENT
Version 4 10-NOV-87
Status: Passed, 1988?

+ SHARPSIGN-PLUS-MINUS-PACKAGE
Version 3 14-NOV-87
Status: Passed, 1988?

+ SPECIAL-TYPE-SHADOWING
Synopsis: intersection of types when proclaimed special has local type
declaration
Version 1, 4-Nov-88, released 11-Jan-89
Status: passed, Jan 89 X3J13

+ STANDARD-INPUT-INITIAL-BINDING
Version 8, 8 Jul 88, Released 7 Oct 88
Status: passed, Jan 89 X3J13

+ STEP-ENVIRONMENT
Version 3, 20-Jun-88, Released  7 Oct 88
Version 4, 17-Mar-89
status: Passed, Jan 89 X3J13, as amended

+ STREAM-ACCESS
Version 2, 30-Nov-88, Released  9 Dec 88
Status: ADD-TYPES-ACCESSORS passed, Jan 89 X3J13

+ SUBSEQ-OUT-OF-BOUNDS
29-MAR-88 Version 2 
Status: Passed, 1988?

* SUBTYPEP-ENVIRONMENT
Version 1, 2-Jan-89
Status: ** missing writeup ***

+ SUBTYPEP-TOO-VAGUE
Version 4,  7-Oct-88, Released 7 Oct 88
Status: passed, Jan 89 X3J13

+ SYMBOL-MACROLET-DECLARE
Version 2,  9-Dec-88, Released 9 Dec 88
Status: passed, Jan 89 X3J13

!+ SYMBOL-MACROLET-SEMANTICS
Version 5, 30-Nov-88, Released 9 Dec 88
Status: Passed, Jan 89 X3J13
Version 6, 14-Mar-89, released 16-Mar-89
Status: ready for vote

+ TAILP-NIL
Version 5, 9-Dec-88, Released 12-Dec-88
Synopsis: Operation of TAILP given NIL
Status: passed, Jan 89 X3J13

+ TEST-NOT-IF-NOT
Version 3, 1 Dec 88, Released 9 dec 
Version 4, 18-Mar-89
Status: Need new version as amended.

! THE-AMBIGUITY
Version 2, 11-Jan-89, Released 11-Jan-89
Comments: typo, sense wrong
Status: tabled, vote on 2

! TIME-ZONE-NON-INTEGER
Version 1, 13-Mar-89, Released 16-Mar-89
Status: ready for vote

+* TYPE-OF-UNDERCONSTRAINED
Version 3, 12-Dec-88, Released 12 Dec 88
Comments: Accepted, with amendments
Version 5, 16-Mar-89
Comments: constraints wrong
Status: ** NEED NEW VERSION ***

! UNDEFINED-VARIABLES-AND-FUNCTIONS
Synopsis: What happens on an undefined function call, unbound variable ref?
Version 1, 29-Nov-88, Released 11-Jan-89
Comments: Lumping SLOT-UNBOUND in with unbound special variables was a mistake,
           as SLOT-UNBOUND is an extension mechanism, not only a safety checking
           mechanism.  Also there were some wording problems.  Gabriel and Gregor
           are to submit a revised proposal.
		No version arrived.
Status: vote on 1?

+ UNREAD-CHAR-AFTER-PEEK-CHAR
Version 2, 2-Dec-88, Released 12-Dec-88
Status: passed, Jan 89 X3J13

+ VARIABLE-LIST-ASYMMETRY
Version 3, 08-Oct-88, Released 9 Dec 88
Status: passed, Jan 89 X3J13

+ WITH-OUTPUT-TO-STRING-APPEND-STYLE
Version 5, 7-JUN-88 
Status: Passed, 1988?

∂20-Mar-89  0002	X3J13-mailer 	X3J13 mailer    
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 20 Mar 89  00:02:29 PST
Received: from relay2.cs.net by RELAY.CS.NET id aa07578; 20 Mar 89 2:47 EST
Received: from utokyo-relay by RELAY.CS.NET id ai28052; 20 Mar 89 2:38 EST
Received: by ccut.cc.u-tokyo.junet (5.51/6.3Junet-1.0/CSNET-JUNET)
	id AA05005; Mon, 20 Mar 89 14:16:29 JST
Received: from kepa.cc.aoyama.junet by aoyama.cc.aoyama.junet (4.0/6.4J.BETA2-agu2)
	id AA08005; Mon, 20 Mar 89 13:59:10 JST
Received: by kepa.cc.aoyama.junet (4.0/6.3Junet-1.0)
	id AA00673; Mon, 20 Mar 89 13:59:37 JST
Date: Mon, 20 Mar 89 13:59:37 JST
From: Masayuki Ida <ida%cc.aoyama.junet@UTOKYO-RELAY.CSNET>
Return-Path: <ida@cc.aoyama.junet>
Message-Id: <8903200459.AA00673@kepa.cc.aoyama.junet>
To: x3j13@SAIL.STANFORD.EDU
Cc: ida%cc.aoyama.junet@UTOKYO-RELAY.CSNET
Subject: X3J13 mailer


I finally found that I did NOT receive ANY X3J13 mails
since March 6 or 7 until today.
I believe something was wrong with the mailer at stanford or
at the japanese gate way.
Editorial mailer, and other mailers are OK.

Anyway, I will attend the Fairfax meeting as a member,
though I have not get any fresh information for two weeks.

Looking forward to seeing you all at Fairfax.

Masayuki Ida

∂20-Mar-89  1229	X3J13-mailer 	Re:  Fatal vesus Harmless 
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 20 Mar 89  12:29:29 PST
Received: from snail.Sun.COM (snail.Corp.Sun.COM) by Sun.COM (4.1/SMI-4.0)
	id AA03785; Mon, 20 Mar 89 12:01:45 PST
Received: from clam.sun.com by snail.Sun.COM (4.1/SMI-4.1)
	id AA18569; Mon, 20 Mar 89 11:57:53 PST
Received: by clam.sun.com (4.0/SMI-4.0)
	id AA02722; Mon, 20 Mar 89 12:01:32 PST
Date: Mon, 20 Mar 89 12:01:32 PST
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8903202001.AA02722@clam.sun.com>
To: RPG@SAIL.Stanford.EDU, x3j13@SAIL.Stanford.EDU
Subject: Re:  Fatal vesus Harmless
Cc: cl-editorial@SAIL.Stanford.EDU

Dick Gabriel's discussion of fatal versus harmless made sense
to me.  I'm going to propose here that within that framework
it can make sense to PERMIT certain SPECIFIED side effects.
I still say that "unspecified by harmless" loses.

To paraphrase, a program P "has fatal consequences"
exactly if it can be preceded and followed by conforming code
so that the entire sequence including P may "crash or abnormally
terminate".

The key question remaining in my mind is what side effects
can be considered harmless.  Dick mentioned a property-list-like
data structure.  Let's talk about hash tables and MAPHASH.
Specifically let's talk about the result of

(let ((result (list)))
  (maphash #'(lambda (key value) (push (list key value) result))
           table)
  result)
  
The order of the result of this expression is unspecified for a
given hash table at a given time, but the set of key-value pairs
is specified.

Is it OK for CONS to cause the order of this list to change?  Is it
OK for CAR to cause it to change?

Since we are trying to discuss harmless side effects, suppose we wish
to allow GC to rehash, possibly changing the order.  The answer must
be that CONS can change the list, because it may invoke the GC.

Since we don't specify what operations can allocate storage, it
appears that we will prefer to say that any operation at all
is permitted to change the value of the example expression above.

In either case, we have no "unspecified but harmless" side
effect of some particular Common Lisp operation.  We have a
particular class of side effects that are PERMITTED
in certain circumstances.  We may choose to specify that
certain classes of side effects are ALWAYS permitted.

We may say that certain side effects are permitted -- to certain
operations.  Suppose we wish to permit certain Common Lisp operations
to issue progress messages, but *not* to consider progress messages as
side effects permitted for all Common Lisp operations.  In
that case it appears to me that we specify that certain operations may
issue progress messages.

While agreeing with Dick Gabriel's recent note, nowhere do I see
the concept "unspecified by harmless" as useful to the definition
of Common Lisp.  Some side effects may be PERMITTED.  Some may even
be permitted to ALL COMMON LISP OPERATIONS.  These are specified
effects, not unspecified effects, and "permitted" I think conveys
the concept much more clearly than "harmless".

∂20-Mar-89  1315	CL-Compiler-mailer 	issue COMPILER-VERBOSITY, version 6
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 20 Mar 89  13:15:01 PST
Received: from maths.bath.ac.uk by NSS.Cs.Ucl.AC.UK   via Janet with NIFTP
           id aa07991; 20 Mar 89 18:58 GMT
Received: from xenakis by mordell.maths.bath.AC.UK id aa19210;
          20 Mar 89 18:59 GMT
To: masinter.pa@xerox.com
CC: cl-compiler@sail.stanford.edu, x3J13@sail.stanford.edu
In-reply-to: masinter.pa@com.xerox's message of 16 Mar 89 05:47 PST <890316-054837-3596@Xerox>
Subject: issue COMPILER-VERBOSITY, version 6
Date: Mon, 20 Mar 89 19:02:07 GMT
From: jpff%maths.bath.ac.uk@NSS.Cs.Ucl.AC.UK
Sender: jpff%maths.bath.ac.uk@NSS.Cs.Ucl.AC.UK

b

∂21-Mar-89  1455	X3J13-mailer 	Issue: COMMON-TYPE (version 1) 
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 21 Mar 89  14:55:40 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 562312; Tue 21-Mar-89 17:55:26 EST
Date: Tue, 21 Mar 89 17:55 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: COMMON-TYPE (version 1)
To: X3J13@SAIL.STANFORD.EDU
References: <19890320162410.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890321225520.0.MOON@EUPHRATES.SCRC.Symbolics.COM>

This issue came up while reviewing section 2.2 of the draft standard.

Issue:         COMMON-TYPE

References:    CLtL p.35, p.76

Category:      CHANGE

Edit history:  Version 1, 20-Mar-89, by Moon

Problem description:
  
  The type COMMON is defined in a very peculiar way and does not seem to
  be useful for anything.  It can be extended by users using DEFSTRUCT,
  but not DEFTYPE nor DEFCLASS, but it cannot be extended by implementations.
  Whether certain types such as NUMBER and ARRAY are subtypes of COMMON
  is implementation-dependent.  The goal of having the COMMON type was
  probably to improve portability, but it is unclear how it could actually
  be used in that way.

Proposal (COMMON-TYPE:REMOVE):

  Remove COMMON and COMMONP from the language.

Rationale:
  
  Keeping the definition of COMMON accurate in the new specification, in
  the face of changes elsewhere in the language such as the introduction
  of CLOS and the possible introduction of character registries, is
  difficult when no one is sure what COMMON is for.  If no one uses COMMON,
  it would be less work to just get rid of it.

Current practice:
  
  Every implementation probably implements COMMON.  Moon has never seen it
  used except in a program to test whether its implementation matched CLtL.

Cost to Implementors:

  None.

Cost to Users:

  None unless they are actually using COMMON.

Cost of non-adoption:
  
  Implementors would have to maintain COMMON.  Users would have to try to
  understand it, or figure out that they didn't care about it.

Performance impact:

  None.

Benefits:

  Simpler language.

Esthetics:

  Simpler language.

Discussion:

  None.

∂21-Mar-89  1500	X3J13-mailer 	Issue: HASH-TABLE-SIZE (version 1)  
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 21 Mar 89  15:00:44 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 562317; Tue 21-Mar-89 18:00:29 EST
Date: Tue, 21 Mar 89 18:00 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: HASH-TABLE-SIZE (version 1)
To: X3J13@SAIL.STANFORD.EDU
References: <19890320165503.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890321230023.2.MOON@EUPHRATES.SCRC.Symbolics.COM>

This issue came up while reviewing section 2.2 of the draft standard.

Issue:         HASH-TABLE-SIZE

References:    CLtL p.283

Category:      CLARIFICATION

Edit history:  Version 1, 20-Mar-89, by Moon

Problem description:
  
  CLtL contradicts itself on the meaning of the :SIZE argument to
  MAKE-HASH-TABLE.  At the top of p.283, it says that the size is "the
  maximum number of entries it can hold.  Usually the actual capacity of
  the table is somewhat less."  At the bottom of the page it says "this
  argument serves as a hint to the implementation of approximately how
  many entries you intend to store."  So does the :SIZE intended to be the
  actual capacity of the table, or the amount of storage allocated to hold
  the table.  For example, if the implementation of hash tables is
  designed for a loading of 65%, and the user specifies :SIZE 100, does
  the table returned have space allocated for 100 entries, so that it
  overflows and becomes bigger when 65 entries are inserted, or does the
  table have space allocated for 154 entries, so that it overflows and
  becomes bigger when 100 entries are inserted?

Proposal (HASH-TABLE-SIZE:INTENDED-ENTRIES):

  Believe the bottom of p.283 rather than the top.  The :SIZE argument
  is approximately the number of entries that can be inserted without
  the table having to grow.

Rationale:
  
  The bottom of p.283 is user-oriented, the top is implementation-oriented.
  User-oriented seems more appropriate.

Current practice:
  
  Symbolics Genera 7.4 adheres to HASH-TABLE-SIZE:INTENDED-ENTRIES.
  Other implementations were not surveyed.

Cost to Implementors:

  At worst adding a multiplication to MAKE-HASH-TABLE.

Cost to Users:

  Probably none, but it is hard to predict.

Cost of non-adoption:
  
  Implementations will probably vary in which of the two interpretations
  they believe.  The language standard will not be self-consistent.

Performance impact:

  None of any significance.

Benefits/Esthetics:

  More self-consistent language.

Discussion:

  None.

∂21-Mar-89  1458	X3J13-mailer 	Issue: COMPLEX-RATIONAL-RESULT (version 1)    
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 21 Mar 89  14:58:19 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 562314; Tue 21-Mar-89 17:58:03 EST
Date: Tue, 21 Mar 89 17:57 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: COMPLEX-RATIONAL-RESULT (version 1)
To: X3J13@SAIL.STANFORD.EDU
References: <19890320164136.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890321225757.1.MOON@EUPHRATES.SCRC.Symbolics.COM>

This issue came up while reviewing section 2.2 of the draft standard.

Issue:         COMPLEX-RATIONAL-RESULT

References:    CLtL p.203

Category:      CLARIFICATION

Edit history:  Version 1, 20-Mar-89, by Moon

Problem description:
  
  Referring to irrational and transcendental functions, CLtL says:
    
    When the arguments to a function in this section are all rational and
    the true mathematical result is also (mathematically) rational, then
    unless otherwise noted an implementation is free to return either an
    accurate result of type rational or a single-precision floating-point
    approximation.  If the arguments are all rational but the result cannot
    be expressed as a rational number, then a single-precision
    floating-point approximation is always returned.

  Referring to EXPT, CLtL says:

    If the base-number is of type RATIONAL and the power-number is an
    INTEGER, the calculation will be exact and the result will be of
    type RATIONAL; otherwise a floating-point approximation may result.

  What about arguments of type (complex rational)?

Proposal (COMPLEX-RATIONAL-RESULT:EXTEND):

  Extend the paragraph quoted above to cover the components of complex
  numbers.  For (complex rational) arguments, a mathematically rational
  result can be rational, (complex rational), or (complex float) at the
  discretion of the implementation.  For EXPT of a (complex rational) to
  an integer power, the calculation must be exact and the result will
  be rational or (complex rational).

Examples:

  (log #c(-16 16) #c(2 2)) => 3 or approximately #c(3.0 0.0)
  (expt #c(2 2) 3) => #c(-16 16)
  (expt #c(2 2) 4) => -64 

Rationale:
  
  This seems most consistent with the treatment of real numbers.

Current practice:
  
  Symbolics Genera 7.4 returns a (complex float) for the first example
  and returns the specified answers for the second and third examples.
  Other implementations were not surveyed.

Cost to Implementors:

  Only EXPT would have to change, since the type of the other results
  is at the discretion of the implementation.

Cost to Users:

  Probably none, but it is hard to predict.

Cost of non-adoption:
  
  Slightly less self-consistent language.

Performance impact:

  None of any significance.

Benefits/Esthetics:

  More self-consistent language.

Discussion:

  None.

∂21-Mar-89  1453	X3J13-mailer 	Issue: PATHNAME-COMPONENT-VALUE (version 1)   
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 21 Mar 89  14:53:02 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 562306; Tue 21-Mar-89 17:52:49 EST
Date: Tue, 21 Mar 89 17:52 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: PATHNAME-COMPONENT-VALUE (version 1)
To: X3J13@SAIL.STANFORD.EDU
References: <19890320180405.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890321225242.9.MOON@EUPHRATES.SCRC.Symbolics.COM>

This issue came up while reviewing section 2.2 of the draft standard.

Issue:         PATHNAME-COMPONENT-VALUE

Related Issues:PATHNAME-CANONICAL-TYPE,
               PATHNAME-SUBDIRECTORY-LIST,
               PATHNAME-UNSPECIFIC-COMPONENT,
               PATHNAME-WILD

References:    CLtL pp.410-3

Category:      CLARIFICATION and CHANGE

Edit history:  Version 1, 20-Mar-89, by Moon

Problem description:
  
  CLtL is overly restrictive on the possible values for pathname components.
  These restrictions are described in a funny way that makes it unclear
  whether they are requirements, guidelines, or just an example.
  
  The restrictions are not all written down in one place, but they appear
  to be as follows:

  Host          nil, :wild, string, or list of strings
  Device        nil, :wild, string, or something else ("structured")
  Directory     nil, :wild, string, or something else ("structured")
  Name          nil, :wild, string, or something else ("structured")
  Type          nil, :wild, or string
  Version       nil, :wild, :newest, positive integer, implementation
                dependent symbol, or implementation-dependent integer
                less than or equal to zero.  Suggestions include :oldest,
                :previous, :installed, 0, and -1.

  PATHNAME-UNSPECIFIC-COMPONENT:NEW-TOKEN allowed implementations to
  allow any component to be :UNSPECIFIC.  This has been voted in.

  PATHNAME-SUBDIRECTORY-LIST proposes a list of strings and keyword
  symbols for the directory component.

  PATHNAME-CANONICAL-TYPE proposes some new operations but does not
  change the possible values of the type component.

  PATHNAME-WILD proposes a portable way to test for implementation
  dependent component values that indicate wildcard matching.  It
  does not change the possible values of any component.

Proposal (PATHNAME-COMPONENT-VALUE:SPECIFY):

  The points of the proposal have been numbered to facilitate
  amendments to remove or modify individual points.

  When examining pathname components, conforming programs must be
  prepared to encounter any of the following values:

  1. Any component can be NIL, which means the component has not
  been specified.

  2. Any component can be :UNSPECIFIC, which means the component has
  no meaning in this particular pathname.

  3. Any component can be :WILD, which matches any component value.
  Wild pathnames can be used with DIRECTORY but not with OPEN.

  4. The host, device, directory, name, and type can be strings.

  5. The host and device can be a list, a structure, or a
  standard-object at the discretion of the implementation.

  6. The directory can be a list of strings and symbols as detailed in
  PATHNAME-SUBDIRECTORY-LIST (this assumes that it passes.)

  7. The version can be any symbol or any integer.  The symbol :NEWEST
  refers to the largest version number that already exists in the file
  system when reading, overwriting, appending, superseding, or directory
  listing an existing file, and refers to the smallest version number
  greater than any existing version number when creating a new file.

  When constructing a pathname from components, conforming programs
  must follow these rules:
  
  11. Any component can be NIL.  NIL in the host may mean a default host
  rather than an actual NIL in some implementations.

  12. Any component can be :WILD, which matches any component value.
  Wild pathnames can be used with DIRECTORY but not with OPEN.
  
  13. The host, device, directory, name, and type can be strings.

  14. The directory can be a list of strings and symbols as detailed in
  PATHNAME-SUBDIRECTORY-LIST (this assumes that it passes.)

  15. The version can be :NEWEST.

  16. Any component can be taken from the corresponding component
  of another pathname on the same host and device.

  17. An implementation might support other values for some
  components, but a portable program cannot use those values.  
  An implementation might allow values to be transferred between
  pathnames on different hosts or different devices, but a portable
  program cannot rely on that.
  A conforming program can use implementation-dependent values
  but this can make it non-portable, for example, it might work
  only with Unix file systems.

  18. It is suggested, but not required, that implementations use
  positive integers starting at 1 as version numbers, recognize
  the symbol :oldest to designate the smallest existing version
  number, and use keyword symbols for other special versions.

Consequences:

  The changes relative to CLtL plus PATHNAME-UNSPECIFIC-COMPONENT
  are as follows:

  The definition of "structured" component is restricted to lists,
  structures, and standard-objects, rather than allowing any object
  whatsoever.
  
  "Structured" hosts are allowed, a generalization of CLtL's list
  of strings.

  "Structured" directories are replaced by PATHNAME-SUBDIRECTORY-LIST.

  "Structured" names are forbidden.

  The difference between what component values a program can depend
  on being able to use, versus what component values a program must
  be prepared to encounter, is clarified.

Rationale:
  
  This should make it easier to write portable programs that deal with
  pathnames and make it easier for implementors by clarifying the
  framework into which they must fit.  Also it should make it easier
  to write the Common Lisp language specification by resolving some
  things that were unclear about the status quo.

  Adding "structured" hosts conforms to current practice.

  Substituting a default host for NIL conforms to current practice
  in implementations that require all pathnames to have a specific host.

  Removing "structured" names should improve portability without causing
  any harm, assuming no implementation uses structured names.  This will
  improve portability by allowing programs to do string manipulation on
  names, although such programs still have to be careful since the valid
  characters and maximum length of a name are implementation-dependent.

  Disallowing transferral of nonstandard component values between
  different hosts or different devices allows implementations to support
  multiple incompatible file systems.

Current practice:
  
  All versions of Symbolics Genera violate CLtL in the matter of hosts,
  since it uses standard-objects as the host component.  Genera deviates
  slightly from PATHNAME-SUBDIRECTORY-LIST, but otherwise conforms to
  PATHNAME-COMPONENT-VALUE:SPECIFY.

  Other implementations were not surveyed.

  This proposal assumes that no current or planned implementation
  uses structured names, not even for wildcards.

Cost to Implementors:

  Most implementations already conform, except for the changes required
  by PATHNAME-UNSPECIFIC-COMPONENT and PATHNAME-SUBDIRECTORY-LIST, so
  the cost of this proposal itself should be minimal.  It is conceivable
  that an implementation may exist that has to change its pathname
  representation, for example one that uses numbers as structured devices.

Cost to Users:

  None.

Cost of non-adoption:
  
  Pathnames will continue to be a poorly specified part of the language.

Performance impact:

  None of any significance.

Benefits/Esthetics:

  The boundary between the specified behavior of pathnames and the
  implementation-dependent behavior of pathnames will be more clear.

Discussion:

A possible alternative to item 16 that's worth considering is:

      16. Any component can be taken from the corresponding component
      of another pathname.  When the two pathnames are for incompatible
      file systems (in implementations that support multiple file
      systems), an appropriate translation occurs.  If no meaningful
      translation is possible, an error is signalled.  The definition
      of "appropriate" and "meaningful" is implementation-dependent.

This provides more useful behavior that conforming programs can 
depend upon, but the behavior cannot be as precisely specified.
A significant amount of the Symbolics Genera pathname facility is
related to this capability, and it's used a lot in heterogeneous
networks, so maybe this is a useful capability that ought to be
called for in the language.  The cost to implementors is small since
they could define "appropriate" and "meaningful" to be whatever is
easiest for them, if their users don't complain.

∂21-Mar-89  1629	X3J13-mailer 	Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 21 Mar 89  16:29:22 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 562415; Tue 21-Mar-89 19:29:06 EST
Date: Tue, 21 Mar 89 19:28 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)
To: X3J13@SAIL.STANFORD.EDU
References: <19890317213333.3.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19890322002858.7.MOON@EUPHRATES.SCRC.Symbolics.COM>

This version is edited to clarify that the semantics of simple-array
are not being changed, and supersedes version 8 which you already saw.

Issue:        ADJUST-ARRAY-NOT-ADJUSTABLE
References:   ADJUST-ARRAY (p297), ADJUSTABLE-ARRAY-P (p293),
              MAKE-ARRAY (pp286-289), simple arrays (p28, 289)
Category:     CLARIFICATION
Edit history: 22-Apr-87, Version 1 by Pitman
              15-Nov-88, Versions 2a,2b,2c by Pitman
              02-Dec-88, Version 3 by Pitman
              11-Jan-89, Version 4 by Pitman
              16-Jan-89, Version 5, by Gabriel.  Amended at the meeting to shorten.
              23-Jan-89, Version 6, by Moon.  Shorten without the bug introduced
                        by the amendment, add clarification of SIMPLE-ARRAY type.
	      15-Feb-89, Version 7, by Pitman. Minor changes per comments from
			RPG and Dalton.
	      11-Mar-89, Version 8, by Pitman. Change category, add endorsements.
              17-Mar-89, Version 9, by Moon, fix wording and examples to make it
			clear that the semantics of simple-array is unchanged.

Problem Description:

  The description of the :ADJUSTABLE option to MAKE-ARRAY on p288
  says that ``the argument, if specified and not NIL, indicates that
  it must be possible to alter the array's size dynamically after
  it is created. This argument defaults to NIL.''

  The description of the :ADJUSTABLE option does not say what 
  MAKE-ARRAY will do if the argument is unsupplied or explicitly NIL.

  The description of ADJUSTABLE-ARRAY-P on p293 says that it is
  true ``if the argument (which must be an array) is adjustable, and
  otherwise false.'' However, the description of MAKE-ARRAY makes
  it clear that this is not necessarily the same as asking if
  the array was created with :ADJUSTABLE T. If ADJUSTABLE-ARRAY-P
  returns NIL, you know that :ADJUSTABLE NIL was supplied (or no
  :ADJUSTABLE option was supplied), but if ADJUSTABLE-ARRAY-P returns
  T, then there is no information about whether :ADJUSTABLE was used.

  The description of ADJUST-ARRAY on pp297-298 says that it is
  ``not permitted to call ADJUST-ARRAY on an array that was not
  created with the :ADJUSTABLE option.'' This is inconsistent with
  ADJUSTABLE-ARRAY-P.
  
  A problem which comes up in practice is that some programmers
  expect runtime error checking if they have done
  (MAKE-ARRAY ... :ADJUSTABLE NIL) and they later try to adjust
  the array using ADJUST-ARRAY.

  The definition of the SIMPLE-ARRAY type and its subtypes needs
  clarification of its relationship to adjustability.


Proposal (ADJUST-ARRAY-NOT-ADJUSTABLE:CLARIFY):

  1. ADJUSTABLE-ARRAY-P is true of all arrays created with a true
  :ADJUSTABLE option to MAKE-ARRAY.  Whether ADJUSTABLE-ARRAY-P is
  true of some other arrays is unspecified.
 
  2. If MAKE-ARRAY is called with the :ADJUSTABLE, :FILL-POINTER, 
  and :DISPLACED-TO arguments each either unspecified or false, the
  resulting array is a simple array.  (This just repeats what CLtL
  says on page 289, it's here to aid in understanding the next point.)
      
  3. If MAKE-ARRAY is called with one or more of the :ADJUSTABLE,
  :FILL-POINTER, or :DISPLACED-TO arguments true, whether the
  resulting array is simple is unspecified.
      
  4. ADJUST-ARRAY ``should signal'' an error if ADJUSTABLE-ARRAY-P
  of its first argument is false.  ADJUST-ARRAY must not signal an
  `array not adjustable' error if ADJUSTABLE-ARRAY-P of its first
  argument is true.

  5. The value of ADJUSTABLE-ARRAY-P on a simple array is unspecified.

  Note: ``should signal'' is taken from the new error terminology.
  It means that in ``safe code'' (code compiled with highest safety)
  an error must be signalled, but that in unsafe code (code not compiled
  with highest safety), an error might or might not be signalled.

Clarifications and Logical Consequences:

  a. Whether an array can be both simple and adjustable is unspecified.

  b. There is no specified way to create an array for which ADJUSTABLE-ARRAY-P
     definitely returns NIL.

  c. There is no specified way to create an array that is non-simple.

  d. This legitimizes ADJUSTABLE-ARRAY-P as an appropriate predicate to
     determine whether ADJUST-ARRAY will reliably succeed.

  e. If ADJUST-ARRAY is invoked on an array that was created without
     supplying :ADJUSTABLE true, an `array not adjustable' error
     ``should be signalled'' unless ADJUSTABLE-ARRAY-P returns true on
     that array (in which case it must not signal an `array not adjustable'
     error).

  f. There is no change to the meaning of the type SIMPLE-ARRAY, only
     a clarification that a conforming program cannot assume that any
     array is not simple.

Rationale:

  This effectively makes the status quo explicit.  This preserves the
  raison d'etre of simple arrays, which is to provide a portable interface
  to implementation-dependent specialized arrays that trade decreased
  functionality for faster access.

  A proposed alternative was to specify a way to create an array that is
  guaranteed not to be simple.  This would have required large changes
  to some implementations and would be of little benefit to users.
  Users need to know that certain arrays are simple, so they can put in
  declarations and get higher performance, but users have no need to be
  able to create arrays that are definitely non-simple (for lower
  performance) or definitely non-adjustable (to cause errors).

Examples:

  1. The following program is conforming.  It is unspecified which branch
  of the IF it follows.
  
    (defun double (a)
       (if (adjustable-array-p a)
           (adjust-array a (* (length a) 2))
           (let ((new (make-array (* (length a) 2))))
             (replace new a :end1 (length a))
             new)))
  
    (double (make-array 30))

  2. The following program is conforming.  In no implementation is the
  type declaration violated.

    (let ((a (make-array 100)))
      (declare (simple-array a))
      (frob a))

  3. The following program is non-conforming.  The consequences of this
  program are undefined because the type declaration is violated in some
  valid implementations.

    (let ((a (make-array 100 :adjustable t)))
      (declare (simple-array a))
      (frob a))


Current Practice:

  Probably everyone is compatible with this proposal. 

  Symbolics Genera makes :ADJUSTABLE NIL arrays adjustable in most cases,
  and ignores adjustability in deciding whether an array is simple,
  and is compatible with this proposal.

  Lucid, IIM, and Symbolics Cloe make :ADJUSTABLE NIL arrays non-adjustable
  in all cases, and make all arrays non-simple unless the Common Lisp
  language requires them to be simple, and are compatible with this proposal.

Cost to Implementors:

  It's in principle possible that some implementation would have to change,
  but in practice there are no known implementations that would have to change.

Cost to Users:

  None. This is a fully compatible change from the user's standpoint.

Benefits:

  Users would know what to expect.

Non-Benefits:

  Users who expect adjusting arrays created with :ADJUSTABLE NIL to signal
  an error would not get the desired error checking.

Aesthetics:

  Most people believe the status quo is unaesthetic.  Having an aspect of
  the language explicitly unspecified is more aesthetic than having it
  implicitly unspecified on account of vague or inconsistent documentation.

Discussion:

  Pitman, Moon, Gabriel, and Steele support this amended proposal.

  MACSYMA ran into portability problems due to the status quo.
  If the issue had been documented, that would have helped.
  Encouraging implementations that are able to at least make
  (MAKE-ARRAY ... :ADJUSTABLE NIL) create non-adjustable arrays
  where possible would help, too.

  We considered proposals to incompatibly change this primitive in a
  variety of ways, but the community was very split with strong proponents
  and opponents of each alternate proposal.

  The overriding concern driving this proposal is that Symbolics 
  has asserted that most of the other really interesting proposals would
  likely involve a sizable cost to implementors (and their installed bases)
  to implement what were judged by some as gratuitous changes from the
  status quo.

  Pitman wishes some of the other proposals were economically feasible to
  pursue but reluctantly agrees that maintaining (and clearly documenting)
  the status quo is probably the most reasonable avenue left to us.

∂21-Mar-89  1732	CL-Compiler-mailer 	**DRAFT** issue CLOS-MACRO-COMPILATION, version 2 
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 21 Mar 89  17:32:46 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 562475; Tue 21-Mar-89 20:32:29 EST
Date: Tue, 21 Mar 89 20:32 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** issue CLOS-MACRO-COMPILATION, version 2
To: cl-compiler@SAIL.STANFORD.EDU
cc: x3j13@SAIL.STANFORD.EDU
In-Reply-To: <8903132248.AA02496@defun.utah.edu>
Message-ID: <19890322013216.0.MOON@EUPHRATES.SCRC.Symbolics.COM>

I would go with MINIMAL for now.  It leaves a lot of behavior
unspecified, and we can fill in that behavior later when we
add metaobjects to the standard.

Relatively small comments:

The compiler should be allowed to warn, but not error, about
failures of lambda-list congruence between methods or generic
functions in the file being compiled and methods or generic
functions in the Lisp doing the compilation.  When you say
the compiler may not "perform tests" between these, it's not
clear whether you mean to rule out only errors or both errors
and warnings.

The only thing here that might be overspecification is allowing a
DEFINE-METHOD-COMBINATION to be used later in the same compilation.
However, I see no real harm in that, and it would often be 
convenient for programmers, so leave it.  But if someone else
moves to remove it, I will not object.

Evaluation of the form in EQL parameter specializer names in DEFMETHOD
needs to be covered.  I think this is tied up with the pending compiler
committee issue DEFCONSTANT-VALUE (whose version 2 writeup I don't like,
it's too messy).  The choices seem to be to require the form in an EQL
parameter specializer name to be evaluable at compile time, to require
it to depend only on constants defined in the file being compiled, or to
permit its evaluation to be deferred until load time.  I don't like the
first choice.  I think for both DEFCONSTANT and EQL the semantics should
be as if it were never evaluated until load time, with the compiler
allowed to evaluate it sooner only if it can prove that that does not
change the semantics.  I'd be happier if the mechanism the compiler
uses to do this tentative evaluation were made available to the user,
but that can be deferred until metaobjects.

∂21-Mar-89  2048	X3J13-mailer 	Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 21 Mar 89  20:48:46 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA01278g; Tue, 21 Mar 89 20:43:21 PST
Received: by challenger id AA22664g; Tue, 21 Mar 89 20:38:38 PST
Date: Tue, 21 Mar 89 20:38:38 PST
From: Richard P. Gabriel <rpg@lucid.com>
Message-Id: <8903220438.AA22664@challenger>
To: x3j13@sail.stanford.edu
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)


People have continued to debate this issue. Part of the confusion is
what CLtL really says about simple arrays and adjustability.  The
cause of the confusion is that various people have advanced difficult
to understand arguments and proposals (myself included).

As mentioned in the statement of ADJUST-ARRAY-NOT-ADJUSTABLE (Version
9), I agreed to support it, and I also agreed that it was a
clarification and not a change,

Because I had become confused by the issue, I decided to go back to
CLtL to find the consistent readings of the passages on simple arrays
and adjustability. As part of this exercise I tried to write up an
analysis of the possible interpretations of the the statements in
question. I often use this hermeneutical act to understand difficult
issues. 

The result is that I think there are exactly two plausible consistent
readings, with one much more plausible than the other. Both readings
are inconsistent with ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9).
Therefore, I conclude that ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9) is
a change, not a clarification, and I must withdraw my agreement that
it is a clarification.

Whether we wish to adopt it is another question, to which I offer no
specific comment or suggestion. I am convinced that if some people
have read CLtL as meaning what ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)
states and implemented simple arrays that way, we are in quite a bind.

The only minor comment I have is a general one: We should be wary of
changes (rather than clarifications) at this stage of standardization.

This message is very long and contains lots of close reasoning and
boring details.  By its length and detail some might read it as a
strong criticism of the authors of ADJUST-ARRAY-NOT-ADJUSTABLE
(Version 9) - it really isn't (in fact, before I this exercise I
believed that the contents of ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)
would be one of the plausible interpretations).  It is simply what I
found and how I found it.

If you want to get to the heart of the matter, ask your text editor to
search for <<yoo-hoo>> and start reading there.

*************************
* Start of the Analysis *
*************************

In this message I will use the notation (S-i) to name statements;
(S-8) is to be read as ``statement 8.''  I will use (I-i-j) to name
interpretations of statments; (I-8-2) is to be read as ``the second
interpretation of statement 8.''  (I-7;8-4) is to be read as ``the
fourth interpretation of the statements 7 and 8 taken together.''  I
will use (*I-i-j) to name incorrect interpretations of statements;
(*I-8-2) is to be read as ``the (incorrect) second interpretation of
statement 8.'' I will use (C-i[J1,...,Jn) to name conclusions derived
from statements; (C-2[S-1,I-8-2]) is to be read as ``conclusion 2
derived from statement 1 and the second interpretation of statement
8.''

There are several relevant statements in CLtL.

(S-1) [from Page 28] An array that is not displaced to another array,
has no fill pointer, and is not to have its size adjusted dynamically
after creation is called a simple array.

(S-2) [from Page 288] :ADJUSTABLE: This argument, if specified and not
NIL, indicates that it must be possible to alter the array's size
dynamically after it is created.

(S-3) [immediately follows (S-2)] This argument defaults to NIL.

(S-4) [from Page 289] If MAKE-ARRAY is called with the :ADJUSTABLE,
:FILL-POINTER, and :DISPLACED-TO arguments each either unspecified or
false, the resulting array is a simple array.

(S-5) [from Page 293] This predicate [ADJUSTABLE-ARRAY-P] is true if
the argument (which must be an array) is adjustable, and otherwise
false.

(S-6) [from Page 297] It is not permitted to call ADJUST-ARRAY on an
array that was not created with the :ADJUSTABLE option.  

(S-7) [immediately follows (S-6)] The predicate ADJUSTABLE-ARRAY-P may
be used to determine whether or not an array is adjustable.

First, let's look at the various interpretations of these statements.

***************************
* Interpretation of (S-1) *
***************************

The statement (S-1) appears to be in the form of a definition.
However, the phrase ``is called'' could be taken as a non-standard way
to introduce a definition and might instead be taken as a conditional
statement: Schematically, ``X's are called Y's'' could be taken to
mean ``If something is an X, then it is a Y.''

I don't think this is a plausible reading in a programming language
specification. Consider this sentence:

``A number that is divisible by 9 is called a well-tempered number.''

I think this is a fair definition. Certainly we would say that, by
this definition, the number 11 is not a well-tempered number.

Nevertheless, a possible interpretation of (S-1) could be:

(*I-1-1) If an array is not displaced to another array, has no fill
pointer, and is not to have its size adjusted dynamically after
creation, it is a simple array (and there may be simple arrays that do
not satisfy these properties).

However, if we look at the other statements in Chapters 2 and 17 we
see the use of ``is called'' throughout in what appears to be a
definitional sense. If (S-1) lacks definitional force, then so do
these statements:

Page 29: One-dimensional arrays are called vectors in Common Lisp
and constitute the type VECTOR (which is therefore a subtype
of ARRAY).

Page 29: All implementations provide specialized arrays for the cases
when the components are characters (or rather, a special subset of the
characters); the one-dimensional instances of this specialization are
called strings.

Page 29: All implementations are also required to provide specialized
arrays of bits, that is, arrays of type (ARRAY BIT); the
one-dimensional instances of this specialization are called bit
vectors.

Page 286: One-dimensional arrays are called vectors.

Page 286: Vectors whose elements are restricted to type STRING-CHAR
are called strings.

Page 286: Vectors whose elements are restricted to type BIT are called
bit-vectors.

Nothing but one-dimensional arrays are called or considered vectors,
and so I think ``is called'' can reasonably be interpreted only as
definitional.

I believe (*I-1-1) is not reasonable by the two arguments of incorrect
form for a conditional and the use of the ``is called'' form in
definitional senses elsewhere in Chapter 2.

I believe the definitional interpretation of (S-1) is this:

(I-1-1.5) Definition: An array is called a simple array if and only if
the array is not displaced to another array, has no fill pointer, and
is not to have its size adjusted dynamically after creation.

Further, I think the obvious meaning of (S-1) is this:

(I-1-2) Definition: An array is called a simple array if and only if
the array is not displaced to another array, has no fill pointer, and
cannot have its size adjusted dynamically after creation.

Another interpretation of (S-1) is possible. Note that the that the
phrase ``is not to have its size adjusted dynamically after creation''
is used rather than the less equivocal ``cannot have its size adjusted
dynamically after creation.''  One way to understand this phrasing is
as a stylistic device to produce the relatively uniform pattern ``an
array that is, ..., has, ...  and is...'' rather than the relatively
non-uniform pattern ``an array that is, ..., has, ...  and can....'' I
believe that this stylistic nuance is what Steele had in mind, but an
alternative is possible.

The alternative is derived as follows: If something ``is not to be''
acted upon in some particular way, then it is not the *intention* of
the actor to act upon that thing in that way. Therefore, we have the
alternative interpretation:

(I-1-3) Definition: An array is called a simple array if and only if
the array is not displaced to another array, has no fill pointer, and
is not intended to have its size adjusted dynamically after creation.

This results in a curious meaning for ``simple array.'' A simple array
is a legitimate type (SIMPLE-ARRAY appears on Page 34 in the sentence,
``SIMPLE-ARRAY is a subtype of ARRAY.'' It also appears on page 43 as
one the Common Lisp Standard Type Specifiers, and on Page 42 it
states, ``in Common Lisp, types are named by Lisp objects,
specifically symbols and lists, called type specifiers.''), and so it
must be possible to make such an array and to test objects for this
type. If (typep A 'simple-array) is true, then A is an array that,
among other things, was *intended* to not have its size altered
dynamically after creation.

There is another interpretation of (S-1), which interprets ``is not
to have'' as ``doesn't happen to have.''

(*I-1-4) An array that is not displaced to another array, has no fill
pointer, and doesn't happen to have its size adjusted dynamically
after creation is called a simple array.

I think this is an unlikely interpretation because it is clear that a
simple array can be created, and at the point of creation MAKE-ARRAY
would not know whether the size will happen to be adjusted later.

There is yet another interpretation of (S-1), but it cannot be presented
easily until after some other arguments have been made.

***************************
* Interpretation of (S-2) *
***************************

The statement (S-2) states that the argument :ADJUSTABLE can be used
to create an array whose size can be altered dynamically after
creation.

If (I-1-2) is the correct interpretation, then supplying a non-NIL
:ADJUSTABLE argument results in an array whose size *can* be altered
dynamically after creation, and so an array made this way is not a
simple array.

If (I-1-3) is the correct interpretation, then supplying a non-NIL
:ADJUSTABLE argument results in an array that is *intended* to have
its size altered dynamically after creation, and so an array made this
way is not a simple array.

(C-1[I-1-2,I-1-3,S-2]) Supplying a non-NIL :ADJUSTABLE argument to
MAKE-ARRAY results in a non-simple array.  The basis for this
conclusion is the definitional nature of (S-1) regardless of the two
variants of the definition.

In fact, if we look at the statements regarding :FILL-POINTER and
:DISPLACED-TO, we see that if either of them is supplied and true, the
resulting array is also not simple (using the same argument used for
:ADJUSTABLE).

Therefore, 

(C-2[I-1-2,I-1-3]) An array created with any one of :ADJUSTABLE,
:FILL-POINTER, and :DISPLACED-TO specified and non-NIL is not simple.

***************************
* Interpretation of (S-3) *
***************************

The statement (S-3) has a single interpretation.

***************************
* Interpretation of (S-4) *
***************************

The statement (S-4) states that if all three of the :ADJUSTABLE,
:FILL-POINTER, and :DISPLACED-TO arguments are unspecified or false, a
simple array is produced.

Combining this with (C-2) we get:

(C-3[S-4,C-2]) An array created with any one of :ADJUSTABLE,
:FILL-POINTER, and :DISPLACED-TO specified and non-NIL is not simple.

The force of (S-2) and (S-4) is that only a part of the type structure
of arrays is specified. There is definitely a way to create a simple
array, and definitely ways to create non-simple arrays, but whether
non-simple arrays are further distinguished based on the arguments
:ADJUSTABLE, :FILL-POINTER, and :DISPLACED-TO is not specified.

***************************
* Interpretation of (S-5) *
***************************

We will return to statement (S-5) later. Its interpretation is clear,
but which arrays are adjustable is not.

***************************
* Interpretation of (S-6) *
***************************

Statement (S-6) is quite tricky. 

The problem is with the phrase ``is not permitted''; the question is
whether it is synonymous with ``is an error'' or whether it is
stronger.

The case for ``is not permitted"" being stronger than ``is an error''
is very compelling, I feel. First, taken as an English phrase, it is
strong: If you are not permitted to call ADJUST-ARRAY, then you do not
have permission to call it; in other words, you are not allowed to
call it, calling it is not tolerated, consent was not given to call
it, you do not have license to call it, you are not authorized to call
it, you do not have the opportunity to call it, it is not possible to
call it.

Second, ``is not permitted'' is not listed on Page 6 as one of the
phrases synonymous with ``is an error.'' If Steele wanted to actually
prohibit something, he would not be able to use the relatively
intuitive ``must not'' since that means ``is an error,'' which can be
taken to mean ``is allowed.'' That is, within the linguistic bounds of
CLtL it is possible to interpret the statement ``you must not do X''
as ``you are allowed to do X.''

The phrase ``is not permitted'' is used elsewhere in CLtL. The most
directly informative usage is on Page 72:

``The names NIL and T are constants in Common Lisp. Although they are
symbols like any other symbols, and appear to be treated as variables
when evaluated, it is not permitted to modify their values. See
DEFCONSTANT.''

Changing the values of NIL and T is a pretty serious offense. Steele
could have directly used the wording ``is an error,'' but he chose a
phrase not formally defined. He also could have said that NIL and T
are constants exactly like those defined by DEFCONSTANT, but he chose
informal wording that is stronger than ``is an error.''  Finally, the
advice to see DEFCONSTANT is given, almost as an afterthought.

Here is the main interpretation of (S-6):

(I-6-1) Calling ADJUST-ARRAY on an array that was not created with the
:ADJUSTABLE option is prohibited.

An array is ``adjustable'' if it is capable of being adjusted.
ADJUST-ARRAY is the only function in Common Lisp that can adjust an
array. Therefore, if ``calling ADJUST-ARRAY...is prohibited'' in some
situation, then that array is not adjustable in that situation. The
situation pointed out by (I-6-1) is that the ``array ... was not
created with the :ADJUSTABLE option.''

Combining this with (S-2) we get:

(C-4[I-6-1,S-2]) An array is adjustable if and only if the array was
created with the :ADJUSTABLE option.

Now let's look at the case for (S-6) being permissive.

The remark ``see DEFCONSTANT'' could be taken to mean that NIL and T
are simply constants and are to be treated that way, no more, no less.

Under DEFCONSTANT it states that altering the value of a constant ``is
an error.''

So here is the alternative:

(I-6-2) Calling ADJUST-ARRAY on an array that was not created with the
:ADJUSTABLE option is an error (that is, it is allowed).

***************************
* Interpretation of (S-7) *
***************************

On the face of it, (S-7) is a restatement of (S-5).  The two
alternative readings result from either taking its presence as
relevant or irrelevant. That is, one can either believe that (S-7)
conveys some new information by its location relative to other
statements or that the reading of CLtL is as if (S-7) were deleted

I believe that essentially deleting (S-7) is not reasonable, mostly
because Steele is a better writer than that interpretation would
imply.

The fact that (S-7) immediately follows (S-6) implies that there is
some relation between them.  In a two-sentence paragraph it is odd to
have the second sentence add no information to the first.  The obvious
relation is that ADJUSTABLE-ARRAY-P is the predicate that can be used
to determine whether it is permitted to call ADJUST-ARRAY.

(I-7-1) ADJUSTABLE-ARRAY-P can be used to determine whether or not
ADJUST-ARRAY is permitted.

Consider (I-6-1). Using (C-4), since ADJUST-ARRAY can be called on
exactly those arrays that were created with the :ADJUSTABLE option,
and since ADJUSTABLE-ARRAY-P can be used to determine whether
ADJUST-ARRAY can be used, we get:

(C-5[C-4,S-5]) ADJUSTABLE-ARRAY-P can be used to determine whether or
not an array was created with the :ADJUSTABLE option.

Given this, following (S-6) with (S-7) is natural, because it serves
to reinforce the interpretation (I-6-1) because ADJUSTABLE-ARRAY-P
talks about adjustability. 

Let's put (I-6-1), (I-7-1), and (C-5) together:

(I-6;7-1) ADJUST-ARRAY can be called only on adjustable arrays, that
is, only on arrays created with the :ADJUSTABLE option.
ADJUSTABLE-ARRAY-P can be used to determine whether an array was
created with the :ADJUSTABLE option.

Consider (I-6-2). The effect of (I-7-1) is to reinforce the
interpretation (I-6-2), because (S-7) states that ADJUSTABLE-ARRAY-P
must be used to determine adjustability, not the use of the
:ADJUSTABLE argument in MAKE-ARRAY.

We can rephrase (I-6-2) and (I-7-1) as follows:

(I-6;7-2) Calling ADJUST-ARRAY on an array that was not created with
the :ADJUSTABLE option is an error (that is, it is allowed); and
ADJUSTABLE-ARRAY-P can be used to determine whether or not it is
allowed.

**************************
* Interpretation of CLtL *
**************************

Now let's look at (I-1-2) and (I-1-3).

(I-1-2) can be taken either under (I-6;7-1) or under (I-6;7-2).

Under (I-6;7-1) and recalling (C-2), (C-3), and (C-4) we get:

Position 1: The only simple arrays are those created with the
:ADJUSTABLE, :FILL-POINTER, and :DISPLACED-TO arguments each either
unspecified or false. All simple arrays are not adjustable.  An array
is adjustable if and only if it was created with the :ADJUSTABLE
option.  ADJUSTABLE-ARRAY-P is false of all simple arrays.

There is an affinity between (I-1-2) and (I-6;7-1) because the
:ADJUSTABLE argument states whether it is possible to adjust the
array.

Under (I-6;7-2) and recalling (C-2) and (S-5), we get:

Position 2: The only simple arrays are those created with the
:ADJUSTABLE, :FILL-POINTER, and :DISPLACED-TO arguments each either
unspecified or false. A simple array may or may not be adjustable.  An
array created with the :ADJUSTABLE option unspecified or NIL might be
adjustable.  ADJUSTABLE-ARRAY-P can be used to determine whether an
array is adjustable.

This is weak because (I-1-2), (S-2), and (S-4) taken together implies
that the :ADJUSTABLE argument controls adjustability. (I-6-2) implies
that :ADJUSTABLE unspecified or NIL might result in an adjustable
array.

(I-1-3) must be considered under both (I-6;7-1) and (I-6;7-2).

Looking at (I-1-3) with (I-6;7-1), we get Position 1 again, because the
:ADJUSTABLE arguments signals intent to adjust an array.  Here,
(I-6;7-1) implies that one cannot call ADJUST-ARRAY on an array that
was not intended to be adjusted. I feel this is a weak pair of
interpretations.

Looking at (I-1-3) with (I-6;7-2), we get Position 2 again. Here it is
allowed to call ADJUST-ARRAY on an array that wasn't intended to be
adjusted. There is some affinity between (I-1-3) and (I-6;7-2) because
the :ADJUSTABLE argument signals intention only.  The only intention
that is required to be acted upon is specifying a non-NIL :ADJUSTABLE
argument, which must result in an adjustable array. If your intention
is to not adjust the array, you should not care whether it is actually
adjustable. Therefore, (I-6-2) is a sensibly paired with (I-1-3).

The variations of ``can not be adjusted'' and ``not intended to be
adjusted'' have little differential effect on the final
interpretations except insofar as Position 1 is stronger when paired
with (I-1-2) and Position 2 is stronger with (I-1-3). I believe that
the strength of the argument regarding ``is not permitted'' coupled
with the weakness the plausibility of a type being defined with
respect to intention combine to make Position 1 the stronger
interpretation.

*************************************
* Interpretation of (S-1) Revisited *
*************************************

Given the clearly definitional nature of (S-1), let's look at the
question of whether there is any basis in CLtL for an array created
with one of :ADJUSTABLE, :FILL-POINTER, and :DISPLACED-TO specified
and non-NIL to be simple.

The reasoning for such a situation is as follows: Under Position 2 it
is possible for a simple array to be adjustable.  The expression
(MAKE-ARRAY n :ADJUSTABLE NIL) creates a simple array under Position
2, and so why shouldn't (MAKE-ARRAY n :ADJUSTABLE T), since MAKE-ARRAY
probably ignores the :ADJUSTABLE argument.

For this to be allowed, (S-1) must be a partial or conditional
definition.  That is, (S-1) might be definitional, but only for
certain implementations, or part of the definition might apply only
for certain implementations.  The remainder of the paragraph that
starts with (S-1) continues as follows:

(S-8) The user may provide declarations that certain arrays will be
simple.

(S-9) Some implementations can handle simple arrays in an especially
efficient manner; for example, simple arrays may have a more compact
representation than non-simple arrays.

(S-8) and (S-9) clearly imply that the reason for simple arrays is
efficiency. (S-8) talks about declarations provided by the user.  When
a Common Lisp programmer provides a declaration that does not have
semantic import, this can signal only intention. Therefore, the
interpretation (I-1-3) would seem to make sense.

I believe that nothing in (S-8) and (S-9) alters the definitional
nature of (S-2). The most (S-8) and (S-9) could do is limit its
applicability of the definition.  That is, neither (S-8) nor (S-9)
imply that (S-1) is not a definition, but they could modify the
conditions that the definition predicates.

The paragraph starting with (S-1) could be taken as a description of a
type that is useful only in implementations that act differently
according to the user's intentions as signaled by declarations. Since
(S-4) requires that some arrays be simple, implementations that have
no use for simple arrays are forced to have them.

Another interpretation of (S-1) is then:

(*I-1-5) An array that is not displaced, has no fill pointer, and has
been created with the intention not to have its size altered
dynamically after creation in an implementation that honors
declarations is a simple array.

I think this is a far-fetched reading, particularly since Steele
is capable of stating something like this much more precisely than
with the series (S-1), (S-8), and (S-9).

***********************
* End of the Analysis *
***********************

<<yoo-hoo>>

For those of you who could not stand to read the hermeneutic
arguments, here are the only two consistent readings of CLtL regarding
simple arrays and adjustability.  I believe that Position 1 has the
stronger set of arguments behind it and is, I believe, the preferred
reading:

Position 1: The only simple arrays are those created with the
:ADJUSTABLE, :FILL-POINTER, and :DISPLACED-TO arguments each either
unspecified or false. All simple arrays are not adjustable.  An array
is adjustable if and only if it was created with the :ADJUSTABLE
option.  ADJUSTABLE-ARRAY-P is false of all simple arrays.

Position 2: The only simple arrays are those created with the
:ADJUSTABLE, :FILL-POINTER, and :DISPLACED-TO arguments each either
unspecified or false. A simple array may or may not be adjustable.  An
array created with the :ADJUSTABLE option unspecified or NIL might be
adjustable.  ADJUSTABLE-ARRAY-P can be used to determine whether an
array is adjustable.

Here are the points of ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9). I will
note whether each point is consistent with each of the two Positions
so that Version 9 can be seen to be a change rather than a
clarification:

  1. ADJUSTABLE-ARRAY-P is true of all arrays created with a true
  :ADJUSTABLE option to MAKE-ARRAY.  Whether ADJUSTABLE-ARRAY-P is
  true of some other arrays is unspecified.
 
This weakly contradicts Position 1, since Position 1 states which
arrays are adjustable and which aren't.  It is consistent with
Position 2.

  2. If MAKE-ARRAY is called with the :ADJUSTABLE, :FILL-POINTER, 
  and :DISPLACED-TO arguments each either unspecified or false, the
  resulting array is a simple array.  (This just repeats what CLtL
  says on page 289, it's here to aid in understanding the next point.)

This is simply (S-4).
      
  3. If MAKE-ARRAY is called with one or more of the :ADJUSTABLE,
  :FILL-POINTER, or :DISPLACED-TO arguments true, whether the
  resulting array is simple is unspecified.
      
This contradicts both Position 1 and Position 2.

  4. ADJUST-ARRAY ``should signal'' an error if ADJUSTABLE-ARRAY-P
  of its first argument is false.  ADJUST-ARRAY must not signal an
  `array not adjustable' error if ADJUSTABLE-ARRAY-P of its first
  argument is true.

This is consistent with both Position 1 and Position 2.

  5. The value of ADJUSTABLE-ARRAY-P on a simple array is unspecified.

This contradicts Position 1 and is consistent with Position 2.

Let's also look at the ``Clarifications and Logical Consequences''
presented in the proposal:

  a. Whether an array can be both simple and adjustable is unspecified.

This contradicts Position 1 and is consistent with Position 2.

  b. There is no specified way to create an array for which ADJUSTABLE-ARRAY-P
     definitely returns NIL.

This contradicts Position 1 and is consistent with Position 2.

  c. There is no specified way to create an array that is non-simple.

This contradicts both Position 1 and Position 2. In fact, this
contradicts (S-1) under any reasonable interpretation of it.

  d. This legitimizes ADJUSTABLE-ARRAY-P as an appropriate predicate to
     determine whether ADJUST-ARRAY will reliably succeed.

This is consistent with both Position 1 and Position 2.

  e. If ADJUST-ARRAY is invoked on an array that was created without
     supplying :ADJUSTABLE true, an `array not adjustable' error
     ``should be signaled'' unless ADJUSTABLE-ARRAY-P returns true on
     that array (in which case it must not signal an `array not adjustable'
     error).

This is consistent with both Position 1 and Position 2.

Therefore, ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9) is a change to
CLtL, and in fact, Point 3 (and Consequence C) is a major change.

			-rpg-

∂22-Mar-89  0845	X3J13-mailer 	Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 22 Mar 89  08:45:33 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 562901; Wed 22-Mar-89 11:44:59 EST
Date: Wed, 22 Mar 89 11:44 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)
To: Richard P. Gabriel <rpg@lucid.com>
cc: x3j13@SAIL.STANFORD.EDU
In-Reply-To: <8903220438.AA22664@challenger>
Message-ID: <19890322164453.8.MOON@EUPHRATES.SCRC.Symbolics.COM>

    Date: Tue, 21 Mar 89 20:38:38 PST
    From: Richard P. Gabriel <rpg@lucid.com>

    [603 lines deleted]

    Therefore, ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9) is a change to
    CLtL, and in fact, Point 3 (and Consequence C) is a major change.

Show us any conforming program that would be harmed by this change (if
it is a change, and I don't believe your arguments that it is a change)
"c. There is no specified way to create an array that is non-simple."

∂22-Mar-89  0931	X3J13-mailer 	Issue: SETF-MULTIPLE-STORE-VARIABLES (Version 2)   
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 22 Mar 89  09:31:05 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 562950; Wed 22-Mar-89 12:30:11 EST
Date: Wed, 22 Mar 89 12:29 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: SETF-MULTIPLE-STORE-VARIABLES (Version 2)
To: X3J13@SAIL.STANFORD.EDU
cc: Pavel.pa@XEROX.COM, GSB@STONY-BROOK.SCRC.Symbolics.COM
Message-ID: <19890322172956.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Line-fold: No

This proposal didn't quite make it to the January meeting, due to
unclear responsibilities for who was supposed to update it from the
discussion.  I have filled the gap and made the changes implied by the
discussion back in December of last year.  We can't vote on this if
someone invokes the two-week rule, but perhaps no one will.

Issue:         SETF-MULTIPLE-STORE-VARIABLES

References:    CLtL, pp.93-107
               Lisp Pointers, v2n2, pp.27-41

Category:      ADDITION

Edit history:  Version 1,  5-Dec-88, Pavel
               Version 2, 22-Mar-89, Moon, simplify, update from discussion

Problem description:
  
  The description of GET-SETF-METHOD-MULTIPLE-VALUE on page 107 of CLtL
  states that there are no cases in Common Lisp that allow multiple values
  to be stored into a generalized variable.  This is seen by some as an
  arbitrary decision in light of the fact that a very reasonable semantics
  exists for multiple values being assigned by several Common Lisp macros,
  including SETF.  The rationale on page 103 of CLtL suggests that this
  decision might be changed in the future.

Proposal (SETF-MULTIPLE-STORE-VARIABLES:ALLOW):

  Extend the semantics of the macros SETF, PSETF, SHIFTF, ROTATEF, and
  ASSERT to allow "places" whose SETF methods have more than one "store
  variable".  In such cases, the macros accept as many values from the
  newvalue form as there are store variables.  As usual, extra values
  are ignored and missing values default to NIL.

  Extend the long form of DEFSETF to allow the specification of more
  than one "store variable", with the obvious semantics.

  Clarify that GET-SETF-METHOD signals an error if there would be more
  than one store-variable.

Test Cases/Examples:
  
  (defstruct region width height)
  
  (defun region-size (region)
     (values
        (region-width region)
        (region-height region)))
  
  (defsetf region-size (region) (width height)
     `(values
         (setf (region-width ,region) ,width)
         (setf (region-height ,region) ,height)))
  
  (setf my-reg (make-region :width 10 :height 20))
  => #S(REGION :WIDTH 10 :HEIGHT 20)
  
  (region-size my-reg)
  => 10
     20
  
  (setf (region-size my-reg) (values 30 40))
  => 30
     40
  
  (region-size my-reg)
  => 30
     40        

Rationale:
  
  This change removes an artificial restriction on the semantics of
  several Common Lisp macros, allowing a broader set of contexts in
  which generalized variables can be used.  For example, it is not
  difficult to write a reasonable SETF method for the VALUES function,
  yielding a powerful MULTIPLE-VALUE-SETF form:

        (setf (values (car a) (gethash b 'c) (aref d 13))
              (some-hairy-computation))

  In the language as currently defined, this example would have to be
  written:

        (multiple-value-bind (x y z)
                             (some-hairy-computation)
           (setf (car a)        x
                 (gethash b 'c) y
                 (aref d 13)    z))

  Many other (perhaps more compelling) examples of generalized variables
  holding more than one value can easily be imagined.  Their use,
  however, is severely discouraged by Common Lisp as defined in CLtL,
  since none of the built-in macros will accept them.

  The clarification of GET-SETF-METHOD makes explicit what is implied
  by CLtL (CLtL uses the word "guarantee", whose relationship to
  signalling of errors is unclear).

Current practice:

  I do not know of any implementations that allow all of this extension.
  Xerox Lisp does not signal an error, but this is probably due to a bug
  in GET-SETF-METHOD.  Lucid signals an error in GET-SETF-METHOD.
  Symbolics Genera supports the proposal in SETF and PSETF, but not in
  SHIFTF, ROTATEF, and ASSERT.

Cost to Implementors:

  A relatively minor fix to each of the affected macros suffices.  For
  example, to fix SETF itself, one need only call
  GET-SETF-METHOD-MULTIPLE-VALUE instead of GET-SETF-METHOD and emit a
  MULTIPLE-VALUE-BIND instead of a LET for binding the store variables.

Cost to Users:

  This is an upward-compatible change; no user code must change.

Cost of non-adoption:

  Yet another non-uniformity in the language, yet another piece of
  mechanism without a clear use (GET-SETF-METHOD-MULTIPLE-VALUE).

Benefits:

  Wider applicability of a reasonably nice abstraction, the removal of
  an artificial prohibition.

Aesthetics:

  People may disagree about whether this is a simplification or not.  I
  am firmly on the side that believes that such removal of
  non-uniformities is a simplifying force in the language.

Discussion:

  Pavel supports this proposal.

  Moon supports this proposal except he is not sure about the
  inclusion of ASSERT.

  GSB suggests that this is a clarification rather than an addition,
  because the lack of any predefined setf-methods that use multiple
  store variables should not mean that SETF, etc. should not work with
  such a setf-method if the user defined one.  The problem is that CLtL
  examples such as the ones for SHIFTF on p.98 and the simplified
  definition for SETF on p.107 contradict this proposal, and might have
  been taken as specifications, rather than simplified examples, by
  some readers.

  Predefined SETF methods for such functions as VALUES, CONS, and VECTOR
  could have been proposed, but we refrained.  This proposal is necessary
  to allow the user to write such methods for himself, but if this
  proposal is adopted those setf-methods are very easy to write in
  a portable fashion.

∂22-Mar-89  1401	X3J13-mailer 	**DRAFT** issue: PATHNAME-COMPONENT-CASE (Version 1)    
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 22 Mar 89  14:01:14 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 563174; Wed 22-Mar-89 17:00:57 EST
Date: Wed, 22 Mar 89 17:00 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** issue: PATHNAME-COMPONENT-CASE (Version 1)
To: X3J13@SAIL.Stanford.EDU
Message-ID: <890322170040.4.KMP@BOBOLINK.SCRC.Symbolics.COM>

    >>> PLEASE DO -NOT- REPLY TO THIS ISSUE NOW <<<

At this point, probably no one will read what you would write
anyway.  Instead, think about the issue and organize your thoughts
for in-person discussion at the meeting.

There was a lot of discussion on this issue.  The Cleanup committee is
not in agreement on its disposition.  However, the issue is a real one
that we cannot afford to overlook.  See additional comments at the end
for a survey of points of contention.
 -kmp

-----
Issue:        PATHNAME-COMPONENT-CASE
References:   Pathnames (pp410-413),
	      MAKE-PATHNAME (p416),
	      PATHNAME-HOST (p417),
	      PATHNAME-DEVICE (p417),
	      PATHNAME-DIRECTORY (p417),
	      PATHNAME-NAME (p417),
	      PATHNAME-TYPE (p417)
Category:     CHANGE
Edit history: 1-Jul-88, Version 1 by Pitman
Status:	      For Internal Discussion

Problem Description:

  Issues of case in pathnames are a major source of problems.

  In some file systems, the canonical case is lowercase, in some
  uppercase, in some mixed.

  In some file systems, case matters, in others it does not.

  (NAMESTRING (MAKE-PATHNAME :NAME "FOO" :TYPE "LISP"))
  will produce an `ugly' file name like "FOO.LISP" in many (but not all)
  Common Lisp implementations talking to Unix, for example.

  (NAMESTRING (MAKE-PATHNAME :NAME "foo" :TYPE "lisp"))
  might produce an `ugly' file name like "↑Vf↑Vo↑Vo.↑Vl↑Vi↑Vs↑Vp"
  in a Common Lisp implementation talking to a Tops-20.

  Problems like this make it difficult to use MAKE-PATHNAME for much of
  anything without corrective (non-portable) code.

  Other problems occur in merging because doing
   (NAMESTRING (MERGE-PATHNAMES (MAKE-PATHNAME :HOST "MY-TOPS-20" :NAME "FOO")
	                        (PARSE-NAMESTRING "MY-UNIX:x.lisp")))
  should probably return "MY-TOPS-20:FOO.LISP" but in fact might return
  "MY-TOPS-20:FOO.↑Vl↑Vi↑Vs↑Vp" in some implementations.

  Problems like this make it difficult to use any merging primitives for
  much of anything without corrective (non-portable code).

Proposal (PATHNAME-COMPONENT-CASE:CANONICALIZE):

  Designate a treatment for case in pathname components which is
  distinct from the treatment of case in the namestrings. The treatment
  should be invariant across operating systems.

  If a string given to MAKE-PATHNAME, or returned by any of the
  PATHNAME-xxx accessor operations, is all uppercase, it is said to
  designate a name in the system's "canonical case".

  If a string given to MAKE-PATHNAME, or returned by any of the
  PATHNAME-xxx accessor operations, is all lowercase, it is said to
  designate a name in the system's "anticanonical case".

  If a string given to MAKE-PATHNAME, or returned by any of the
  PATHNAME-xxx accessor operations, is mixed case, it is said
  designate a name in exactly the indicated case.

  Functions such as PARSE-NAMESTRING and NAMESTRING which convert
  from or to native host syntax will perform any necessary conversions
  from internal syntax.

  Note: In fact, this proposal does not require an implementation to
  change its internal representation. It only requires the CL-defined
  accessors to behave as if the internal representation had been changed.
  Whether the actual internal representation is changed is still up to an
  implementation. A consequence of this is that if pathnames print 
  in a way that shows the components individually (such as #S), they
  are not constrained to print the components in any particular case;
  they are constrained only to have definite syntax conventions and to
  be able to invert those conventions at the appropriate time. Any change
  to the way pathnames print is beyond the scope of this proposal.

Test Case:

  (PATHNAME-NAME (PARSE-NAMESTRING "MY-UNIX:/me/foo.lisp"))    => "FOO"
  (PATHNAME-NAME (PARSE-NAMESTRING "MY-TOPS-20:<ME>FOO.LISP")) => "FOO"

Rationale:

  This does not solve the whole pathname problem, but it does improve
  the situation for a clearly defined set of very common problems.

Current Practice:

  Symbolics Genera implements this behavior.

Cost to Implementors:

  While this proposal is compatible with CLtL, it may not be compatible with
  the implementations of CLtL which some implementations have chosen.

  It is possible to isolate the forced changes to the referenced functions
  (MAKE-PATHNAME and the PATHNAME-xxx accessors). Existing functions can be
  renamed, and new functions with the same name can be introduced which simply
  encapsulate case conversion. No further change is forced.

  It may, however, be desirable for an implementation to make a more complete
  overhaul of their representation. In implementations where the implementors
  feel a need to do this, the amount of work may be considerably greater.

Cost to Users:

  Technically, this change is upward compatible.

  In fact, since the existing CLtL spec is so poor, nearly everyone relies
  heavily on implementation-specific behavior since there is little other
  choice. As such, any change is almost certain to break lots of programs,
  in usually superficial but nevertheless important ways. However, if we
  really make the pathname facility more portable, the user community may be
  willing to bear the consequences of these changes.

Cost of Non-Adoption:

  We would be contributing to the perpetuation of the existing fiasco of a
  pathname system.

Benefits:

  The major costs of non-adoption would be avoided.

Aesthetics:

  More code is required, but the code supports a simpler user model.
  Anything that simplifies the user model of pathnames is going to be an
  improvement.

Discussion:

  Pitman suports PATHNAME-COMPONENT-CASE:CANONICALIZE.

-------------------------------------------------------------------

There was a lot of debate internally on CL-Cleanup about this one
which reached no resolution. Rather than include that discussion, I
will sum up what I think are the main discussion points:

 - Uppercase was proposed as the canonical case because it seemed
   most consistent with other parts of the language which are forced
   to use a canonical case (such as symbol names and arguments to
   macro character handlers).

   Some people wish we would use lowercase because they think more
   file systems are lowercase.

   Note well that the choice of a case as the `canonical case'
   internal to Lisp has no technical effect on your ability to
   create filenames in upper, lower, or mixed case under this
   proposal.  This argument is purely an aesthetic one.

   The Symbolics file system (upon which this proposal is based)
   uses lowercase as the preferred case, and yet the use of uppercase
   canonical case has caused no serious technical problems in the
   five or so years that we've field tested this appraoch in 
   an environment that depends critically on heavy use of a variety
   of file systems from the same lisp image.  This is not a 
   pie-in-the-sky idea -- it is implemented and has stood the test of time.

 - This proposal suggests that functions like PATHNAME-NAME return
   and that make-pathname accept strings which are in the interchange
   (canonical) case rather than in the native file system case so that
   pathname components can be retrieved from one pathname and stored
   in a second without regard to whether those two pathnames agreed on
   native case.

   Some people suggested that PATHNAME-NAME and MAKE-PATHNAME should
   work non-portably, using native case information, and that you should
   have to do more work (e.g., supply a keyword argument) to get portable
   code. This strikes me as incompatible with our goals but is technically
   a possible position to take.

   Others suggested that two sets of functions should be available --
   one set for native case (e.g., MAKE-FILENAME, FILENAME-NAME, ...)
   and one for portable case (e.g., MAKE-PATHNAME, PATHNAME-NAME, ...).
   These would make the same kind of object -- they would just support
   different views on the set of operations that you might want on the
   object.  If you follow this approach, the issues become ``who gets
   which names'' and ``does this make the language gratuitously bloated''?

   Some people who wanted parallel paradigms (one for native case, one
   for an interchange/canonical case) seemed to be willing to give up
   that desire if the canonical case was coincidentally chosen to be the
   same as the native case for the file system they worked with.
   ``I'll compromise as long as I don't have to change.''

 - Some people don't use multiple file systems in the same core image
   and don't realize how critical an issue this is to those of use who do.

THE BOTTOM LINE:

 Users deal with this problem day in and day out as they move back and
 forth between different systems.  The solution is within our grasp
 technically -- the key issues to be resolved are aesthetic and political,
 not technical.  In the end, users won't want to hear about the political
 roadblocks. They are trusting us to come up with a solution and we should
 come through. Please be prepared to come at this issue constructively. I
 thank you, and our users will ultimately thank you.

∂22-Mar-89  1900	X3J13-mailer 	Issue: PATHNAME-SUBDIRECTORY-LIST (Version 4) 
Received: from Riverside.SCRC.Symbolics.COM (SCRC-RIVERSIDE.ARPA) by SAIL.Stanford.EDU with TCP; 22 Mar 89  19:00:00 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by Riverside.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 325245; Wed 22-Mar-89 21:59:33 EST
Date: Wed, 22 Mar 89 21:59 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: PATHNAME-SUBDIRECTORY-LIST (Version 4)
To: X3J13@SAIL.STANFORD.EDU
Message-ID: <19890323025928.1.MOON@EUPHRATES.SCRC.Symbolics.COM>

This is a last minute update of this issue to fix the problems found
during discussion of the previous version.  I have fixed typos,
including some critical ones that made the proposal impossible to
understand, standardized terminology, and added specifications for
merging of relative directories and for the subset used in
non-hierarchical file systems.

Issue:          PATHNAME-SUBDIRECTORY-LIST
References:     Pathnames (pp410-413), MAKE-PATHNAME (p416),
                PATHNAME-DIRECTORY (p417)
Category:       CHANGE
Edit history:   18-Jun-87, Version 1 by Ghenis.pasa@Xerox.COM
                05-Jul-88, Version 2 by Pitman (major revision)
                28-Dec-88, Version 3 by Pitman (merge discussion)
                22-Mar-89, Version 4 by Moon (fix based on discussion)
Status:         Trying to be Released
Related-Issues: PATHNAME-COMPONENT-CASE

Problem Description:

  It is impossible to write portable code that can produce a pathname
  in a subdirectory of a hierarchical file system. This defeats much of
  the purpose of having an abstraction like pathname.

  According to CLtL, only a string is a portable value for the directory
  component of a pathname, thus in order to denote a subdirectory, the
  use of separators (such as dots, slashes, or backslashes) would be
  necessary. The very fact that such syntax varies from host to host
  means that although the representation might be "portable", the code
  using that representation is not portable.

  This problem is even worse for programs running on machines on a network
  that can retrieve files from multiple hosts, each using a different OS
  and thus a different subdirectory delimiter.

  Related problems:

  - In some implementations "FOO.BAR" might denote the "BAR" subdirectory
    of "FOO", while in other implementations it would denote a top-level
    directory, because "." is not the separator. To be safe, portable
    programs must avoid all potential separators.

  - Even in implementations where "." is the separator, "FOO.BAR" may be
    recognized by some to mean the "BAR" subdirectory of "FOO" and by others
    to mean `a seven letter directory with "." being a superquoted part of
    its name'.

  - In fact, CLtL does not even say for toplevel directories whether
    the directory delimiter characters are part of the string. eg, is
    "foo" or "/foo" the directory component for a unix pathname
    "/foo/bar.lisp". Similarly, is "[FOO]" or "FOO" the directory
    component for a VMS pathname "[FOO]ME.LSP"?

Proposal (PATHNAME-SUBDIRECTORY-LIST:NEW-REPRESENTATION)

  Remove the "structured" directory feature mentioned on CLtL p.412.
  
  Allow the value of a pathname's directory component to be a list.  The
  car of the list may be either of the symbols :ABSOLUTE or :RELATIVE.
  Each remaining element of the list is a string or one of the keyword
  symbols listed below.  Each string names a single level of directory
  structure.  The strings should contain only the directory names
  themselves -- no separator characters.

  A list whose car is the symbol :ABSOLUTE represents a directory path
  starting from the root directory.  The list (:ABSOLUTE) represents
  the root directory.  The list (:ABSOLUTE "foo" "bar" "baz") represents
  the directory called "/foo/bar/baz" in Unix [except possibly for
  alphabetic case -- that is the subject of a separate issue].

  A list whose car is the symbol :RELATIVE represents a directory path
  starting from a default directory.  The list (:RELATIVE) has the same
  meaning as NIL.  The list (:RELATIVE "foo" "bar") represents the
  directory named "bar" in the directory named "foo" in the default
  directory [except possibly for alphabetic case -- that is the subject
  of a separate issue].

  In place of a string, at any point in the list, keyword symbols may occur
  to indicate special file notations. The following symbols have standard
  meanings; they may not be meaningful for all operating systems, and are
  intended for use only on those operating systems where they have meaning.
  Implementations are permitted to add additional keyword symbols if
  necessary to represent features of their file systems.

   :WILD           - Wildcard match of one level of directory structure.
   :WILD-INFERIORS - Wildcard match of any number of directory levels.
   :UP             - Go upward in directory structure (semantic).
   :BACK           - Go upward in directory structure (syntactic).

  "Syntactic" means that the action of :BACK depends only on the pathname
  and not on the contents of the file system.  "Semantic" means that the
  action of :UP depends on the contents of the file system; to resolve
  a pathname containing :UP to a pathname whose directory component
  contains only :ABSOLUTE and strings requires probing the file system.
  :UP differs from :BACK only in file systems that support multiple
  names for directories, perhaps via symbolic links.  For example,
  suppose that there is a directory
    (:ABSOLUTE "X" "Y" "Z")
  linked to 
    (:ABSOLUTE "A" "B" "C")
  and there also exist directories
    (:ABSOLUTE "A" "B" "Q")
    (:ABSOLUTE "X" "Y" "Q")
  then
    (:ABSOLUTE "X" "Y" "Z" :UP "Q")
  designates
    (:ABSOLUTE "A" "B" "Q")
  while
    (:ABSOLUTE "X" "Y" "Z" :BACK "Q")
  designates
    (:ABSOLUTE "X" "Y" "Q")

  If a string is used as the value of the :DIRECTORY argument to
  MAKE-PATHNAME, it should be the name of a toplevel directory and
  should not contain any directory delimiter characters.  Specifying a
  string, str, is equivalent to specifying the list (:ABSOLUTE str).
  Specifying the symbol :WILD is equivalent to specifying the list
  (:ABSOLUTE :WILD-INFERIORS), or (:ABSOLUTE :WILD) in a
  non-hierarchical file system.

  The PATHNAME-DIRECTORY function never returns a string nor :WILD; it
  always returns NIL, :UNSPECIFIC, or a list.

  In non-hierarchical file systems, the only valid list values for the
  directory component of a pathname are (:ABSOLUTE string) and
  (:ABSOLUTE :WILD).  :RELATIVE directories and the keywords
  :WILD-INFERIORS, :UP, and :BACK are not used in non-hierarchical file
  systems.

  Pathname merging treats a relative directory specially.  Let
  <pathname> and <defaults> be the first two arguments to
  MERGE-PATHNAMES.  If (PATHNAME-DIRECTORY <pathname>) is a list whose
  car is :RELATIVE, and (PATHNAME-DIRECTORY <defaults>) is a list, then
  the merged directory is the value of
    (APPEND (PATHNAME-DIRECTORY <defaults>)
            (CDR (PATHNAME-DIRECTORY <pathname>)))
  except that if the resulting list contains an element other than :BACK
  or :WILD-INFERIORS, immediately followed by :BACK, both of them are
  removed.  This removal of redundant :BACKs is repeated as many times
  as possible.  If (PATHNAME-DIRECTORY <defaults>) is not a list, the
  merged directory is
    (OR (PATHNAME-DIRECTORY <pathname>) (PATHNAME-DIRECTORY <defaults>))

  A relative directory in the pathname argument to a function such as
  OPEN is merged with *DEFAULT-PATHNAME-DEFAULTS* before accessing the
  file system.

Test Cases/Examples:

  (PATHNAME-DIRECTORY (PARSE-NAMESTRING "[FOO.BAR]BAZ.LSP")) ;on VMS
  => (:ABSOLUTE "FOO" "BAR")

  (PATHNAME-DIRECTORY (PARSE-NAMESTRING "/foo/bar/baz.lisp")) ;on Unix
  => (:ABSOLUTE "foo" "bar")
  or (:ABSOLUTE "FOO" "BAR")
  If PATHNAME-COMPONENT-CASE:CANONICALIZE passes, only the 2nd return value.

  (PATHNAME-DIRECTORY (PARSE-NAMESTRING "../baz.lisp")) ;on Unix
  => (:RELATIVE :UP)

  (PATHNAME-DIRECTORY (PARSE-NAMESTRING "/foo/bar/../mum/baz")) ;on Unix
  => (:ABSOLUTE "foo" "bar" :UP "mum")

  (PATHNAME-DIRECTORY (PARSE-NAMESTRING ">foo>**>bar>baz.lisp")) ;on LispM
  => (:ABSOLUTE "FOO" :WILD-INFERIORS "BAR")

  (PATHNAME-DIRECTORY (PARSE-NAMESTRING ">foo>*>bar>baz.lisp")) ;on LispM
  => (:ABSOLUTE "FOO" :WILD "BAR")

Rationale:

  This would allow programs to usefully deal with hierarchical file
  systems, which are by far the most common file system type.

Current Practice:

  Symbolics Genera implements something very similar to this. The main
  differences are:
   - In Genera, there is no :ABSOLUTE keyword at the head of the list.
     This has been shown to cause some problems in dealing with root
     directories. Genera represents the root directory by a keyword
     symbol (rather than a list) because the list representation 
     was not adequately general.
   - Genera represents Unix ".." as :UP, but deals with :UP 
     syntactically, not semantically.

Cost to Implementors:

  In principle, nothing about the implementation needs to change except
  the treatment of the directory component by MAKE-PATHNAME and
  PATHNAME-DIRECTORY. The internal representation can otherwise be left
  as-is if necessary.

  Implementations such as Genera that already have hierarchical directory
  handling will have to make an incompatible change to switch to what
  is proposed here.

  For implementations that choose to rationalize this representation
  throughout their internals and any other implementation-specific
  accessors, the cost will be necessarily higher.

Cost to Users:

  None. This change is upward compatible.

Cost of Non-Adoption:

  Serious portability problems would continue to occur. Programmers would be
  driven to the use of implementation-specific facilities because the need
  for this is frequently impossible to ignore.

Benefits:

  The serious costs of non-adoption would be avoided.

Aesthetics:

  This representation of hierarchical pathnames is easy to use and quite
  general. Users will probably see this as an improvement in the aesthetics.

Discussion:

  This issue was raised a while back but no one was fond of the particular
  proposal that was submitted. This is an attempt to revive the issue.

  The original proposal, to add a :SUBDIRECTORIES component to a
  pathname, was discarded because it imposed an unnatural distinction
  between a toplevel directory and its subdirectories. Pitman's guess is
  the the idea was to try to make it a compatible change, but since most
  programmers will probably want to change from implementation-specific
  primitives to portable ones anyway, that's probably not such a big
  deal. Also, there might have been some programs which thought the
  change was compatible and ended up ignoring important information (the
  :SUBDIRECTORIES component). Pitman thought it would be better if
  people just accepted the cost of an incompatible change in order to
  get something really pretty as a result.

  Moon doesn't like having both :UP and :BACK, but admits that some
  file systems do it one way and some do it the other.

  To keep it simple, we chose not to add to this issue the functions
  DIRECTORY-PATHNAME-AS-FILE and PATHNAME-AS-DIRECTORY, which convert
  the name of a directory from or to the directory component of a file
  inferior to that directory.  This conversion is system-dependent, for
  example TOPS-20 appends a type field and Unix does not.  Also in some
  systems the root directory has a name and in others it doesn't.  Of
  course these functions signal an error in non-hierarchical file
  systems.

∂22-Mar-89  2031	X3J13-mailer 	Issue: PATHNAME-COMPONENT-CASE (Version 2)    
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 22 Mar 89  20:30:42 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 563397; Wed 22-Mar-89 23:30:16 EST
Date: Wed, 22 Mar 89 23:30 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: PATHNAME-COMPONENT-CASE (Version 2)
To: X3J13@SAIL.STANFORD.EDU
Message-ID: <19890323043004.2.MOON@EUPHRATES.SCRC.Symbolics.COM>

I updated and rewrote this issue based on the discussion last Summer and
Autumn that followed the publication of version 1 within the cleanup
committee.  Perhaps we can use this as the basis for a constructive
discussion and get this issue out of the way.

This issue contains four alternative proposals.

Issue:        PATHNAME-COMPONENT-CASE
References:   Pathnames (pp410-413),
              MAKE-PATHNAME (p416),
              PATHNAME-HOST (p417),
              PATHNAME-DEVICE (p417),
              PATHNAME-DIRECTORY (p417),
              PATHNAME-NAME (p417),
              PATHNAME-TYPE (p417)
Category:     CHANGE
Edit history: 1-Jul-88, Version 1 by Pitman
              22-Mar-89, Version 2 by Moon, update and rewrite
Status:       Trying to be ready for release

Problem Description:

  Issues of alphabetic case in pathnames are a major source of problems.

  In some file systems, the customary case is lowercase, in some
  uppercase, in some mixed.  In some file systems, case matters, in
  others it does not.

  There are two kinds of portability problems connected with case in
  pathnames: moving programs from one Common Lisp to another, and moving
  pathname component values from one file system to another.  To solve
  the first problem, all Common Lisp implementations that support a
  particular file system must use compatible representations for
  pathname component values.  To solve the second problem, there must be
  a canonical representation for pathname component values that means
  the same thing on all file systems.

  The desire for a canonical representation for pathname component
  values directly conflicts with the desire among programmers who only
  use one file system to work with the local conventions and not to
  have to think about issues of porting to other file systems.  The
  canonical representation cannot be the same as every local
  convention, since they vary.

  In the current anarchy of pathname component case conventions:
  
  (NAMESTRING (MAKE-PATHNAME :NAME "FOO" :TYPE "LISP"))
  will produce foo.lisp in some Unix Common Lisp implementations
  and will produce FOO.LISP in other Unix Common Lisp implementations.

  (NAMESTRING (MAKE-PATHNAME :NAME "foo" :TYPE "lisp"))
  will produce FOO.LISP in some Tops-20 Common Lisp implementations
  and will produce "↑Vf↑Vo↑Vo.↑Vl↑Vi↑Vs↑Vp"in other Tops-20 Common
  Lisp implementations.

  Problems like this make it difficult to use MAKE-PATHNAME for much of
  anything without corrective (non-portable) code.

  Other problems occur in merging because doing
   (NAMESTRING (MERGE-PATHNAMES (MAKE-PATHNAME :HOST "MY-TOPS-20" :NAME "FOO")
                                (PARSE-NAMESTRING "MY-UNIX:x.lisp")))
  should probably return "MY-TOPS-20:FOO.LISP" but in fact might return
  "MY-TOPS-20:FOO.↑Vl↑Vi↑Vs↑Vp" in some implementations.

  Problems like this make it difficult to use any merging primitives for
  much of anything without corrective (non-portable) code.

Proposal (PATHNAME-COMPONENT-CASE:CANONICALIZE):

  Designate a treatment for case in pathname components which is
  distinct from the treatment of case in the namestrings.  The treatment
  should be invariant across operating systems.  Namestrings use local
  file system case conventions, pathname components use common case
  conventions.

  Arbitrarily choose uppercase as the common (or universal) case.

  If a string given to MAKE-PATHNAME, or returned by any of the
  PATHNAME-xxx accessor operations, is all uppercase, it is said to
  designate a name in the system's "canonical case".

  If a string given to MAKE-PATHNAME, or returned by any of the
  PATHNAME-xxx accessor operations, is all lowercase, it is said to
  designate a name in the system's "anticanonical case".

  If a string given to MAKE-PATHNAME, or returned by any of the
  PATHNAME-xxx accessor operations, is mixed case, it is said to
  designate a name in exactly the indicated case.

  Functions such as PARSE-NAMESTRING and NAMESTRING which convert from
  or to local file system syntax will perform any necessary conversions
  between "canonical case" and the host's customary case, and between
  "anticanonical case" and the opposite of the host's customary case.

Proposal (PATHNAME-COMPONENT-CASE:NEW-COMMON-ACCESSORS):

  Add new pathname component accessor functions that return values
  translated to the common case defined above.  Use the local file
  system case conventions in the existing pathname component accessor
  functions.  The new accessors are named PATHNAME-COMMON-DEVICE,
  PATHNAME-COMMON-DIRECTORY, PATHNAME-COMMON-NAME, and
  PATHNAME-COMMON-TYPE.

  Add new keyword arguments to MAKE-PATHNAME that accept values in the
  the common case defined above and translate to the host's customary
  case.  Use the local file system case conventions in the existing
  keyword arguments to MAKE-PATHNAME.  The new keyword arguments are
  named :COMMON-DEVICE, :COMMON-DIRECTORY, :COMMON-NAME, and
  :COMMON-TYPE.

Proposal (PATHNAME-COMPONENT-CASE:NEW-LOCAL-ACCESSORS):

  Do everything proposed for PATHNAME-COMPONENT-CASE:CANONICALIZE,
  and in addition:
  
  Add new pathname component accessor functions that return values in
  the local file system case conventions.  The new accessors are named
  PATHNAME-LOCAL-DEVICE, PATHNAME-LOCAL-DIRECTORY, PATHNAME-LOCAL-NAME,
  and PATHNAME-LOCAL-TYPE.

  Add new keyword arguments to MAKE-PATHNAME that accept values in the
  local file system case conventions.  The new keyword arguments are
  named :LOCAL-DEVICE, :LOCAL-DIRECTORY, :LOCAL-NAME, and :LOCAL-TYPE.

Proposal (PATHNAME-COMPONENT-CASE:KEYWORD-ARGUMENT):

  Add a keyword argument :CASE to MAKE-PATHNAME and the PATHNAME-xxx
  accessors, indicating whether common or local conventions should be
  followed.  The possible values for the argument are :COMMON and
  :LOCAL.  The default is :COMMON.

Test Case:

  Under PATHNAME-COMPONENT-CASE:CANONICALIZE:

  (PATHNAME-NAME (PARSE-NAMESTRING "MY-UNIX:/me/foo.lisp"))    => "FOO"
  (PATHNAME-NAME (PARSE-NAMESTRING "MY-TOPS-20:<ME>FOO.LISP")) => "FOO"

  Under PATHNAME-COMPONENT-CASE:NEW-COMMON-ACCESSORS:

  (PATHNAME-NAME (PARSE-NAMESTRING "MY-UNIX:/me/foo.lisp"))    => "foo"
  (PATHNAME-NAME (PARSE-NAMESTRING "MY-TOPS-20:<ME>FOO.LISP")) => "FOO"
  (PATHNAME-COMMON-NAME (PARSE-NAMESTRING "MY-UNIX:/me/foo.lisp"))    => "FOO"
  (PATHNAME-COMMON-NAME (PARSE-NAMESTRING "MY-TOPS-20:<ME>FOO.LISP")) => "FOO"

  Under PATHNAME-COMPONENT-CASE:NEW-LOCAL-ACCESSORS:

  (PATHNAME-NAME (PARSE-NAMESTRING "MY-UNIX:/me/foo.lisp"))    => "FOO"
  (PATHNAME-NAME (PARSE-NAMESTRING "MY-TOPS-20:<ME>FOO.LISP")) => "FOO"
  (PATHNAME-LOCAL-NAME (PARSE-NAMESTRING "MY-UNIX:/me/foo.lisp"))    => "foo"
  (PATHNAME-LOCAL-NAME (PARSE-NAMESTRING "MY-TOPS-20:<ME>FOO.LISP")) => "FOO"

  Under PATHNAME-COMPONENT-CASE:KEYWORD-ARGUMENT:

  (PATHNAME-NAME (PARSE-NAMESTRING "MY-UNIX:/me/foo.lisp")
                 :CASE :COMMON)                                 => "FOO"
  (PATHNAME-NAME (PARSE-NAMESTRING "MY-TOPS-20:<ME>FOO.LISP")
                 :CASE :COMMON)                                 => "FOO"
  (PATHNAME-NAME (PARSE-NAMESTRING "MY-UNIX:/me/foo.lisp")
                 :CASE :LOCAL)                                  => "foo"
  (PATHNAME-NAME (PARSE-NAMESTRING "MY-TOPS-20:<ME>FOO.LISP")
                 :CASE :LOCAL)                                  => "FOO"

Rationale:

  This does not solve the whole pathname problem, but it does improve
  the situation for a clearly defined set of very common problems.
  Together with the other pathname proposals, the behavior of pathnames
  should be sufficiently consistent across Common Lisp implementations
  and across file systems to allow portability of pathname-manipulating
  programs.

  Upper case is chosen as the canonical case for no better reason than
  consistency with the canonical case for Lisp symbols.

  PATHNAME-COMPONENT-CASE:CANONICALIZE minimizes the size of the
  language by not adding any new functions.  It assumes that pathname
  operations using local file system conventions can be performed on
  namestrings and that anything that calls MAKE-PATHNAME or the
  PATHNAME-xxx accessors is portable code that is independent of the
  local file system conventions.

  PATHNAME-COMPONENT-CASE:NEW-COMMON-ACCESSORS assumes that the existing
  MAKE-PATHNAME and PATHNAME-xxx accessor features are for programs that
  only work on one file system and that more generally portable programs
  should use new features.

  PATHNAME-COMPONENT-CASE:NEW-LOCAL-ACCESSORS assumes that the existing
  MAKE-PATHNAME and PATHNAME-xxx accessor features are for fully
  portable programs but that PATHNAME-COMPONENT-CASE:CANONICALIZE is
  insufficient and direct access to the local conventions is required.

  PATHNAME-COMPONENT-CASE:KEYWORD-ARGUMENT assumes that access to both
  conventions is necessary but introducing more functions is bad.
  The default convention is the common one, assuming that most
  programs are fully portable.

Note:

  None of these proposals requires an implementation to change its
  internal representation.  They only require the canonical accessors to
  behave as if the internal representation had been changed.  Whether
  the actual internal representation is changed is still up to an
  implementation. A consequence of this is that if pathnames print in a
  way that shows the components individually (such as #S), they are not
  constrained to print the components in any particular case; they are
  constrained only to have definite syntax conventions and to be able to
  invert those conventions at the appropriate time. Any change to the
  way pathnames print is beyond the scope of this proposal.

  There should probably be a remark somewhere that says that portable
  programs shouldn't expect to be able to create and/or access distinct
  files whose pathname components differ only in case.

Current Practice:

  Symbolics Genera implements something resembling
  PATHNAME-COMPONENT-CASE:NEW-LOCAL-ACCESSORS except that the names use
  "raw" rather than "local".  The "raw" accessors are almost never used.
  Symbolics Genera's own file system uses lower case as the customary
  case, but transparent network access is available to file systems
  using all known case conventions.

  Many Common Lisp implementations that only deal with a single file
  system implement something resembling
  PATHNAME-COMPONENT-CASE:NEW-COMMON-ACCESSORS except without the
  new accessors and keyword arguments.

Cost to Implementors:

  While all of these proposals are compatible with CLtL, since CLtL is
  so vague, they are not likely to be compatible with the
  implementations of CLtL which some implementations have chosen.

  It is possible to isolate the forced changes to the referenced functions
  (MAKE-PATHNAME and the PATHNAME-xxx accessors). Existing functions can be
  renamed, and new functions with the same name can be introduced which simply
  encapsulate case conversion. No further change is forced.

  It may, however, be desirable for an implementation to make a more complete
  overhaul of their representation. In implementations where the implementors
  feel a need to do this, the amount of work may be considerably greater.

Cost to Users:

  Technically, this change is upward compatible.

  In fact, since the existing CLtL spec is so poor, nearly everyone relies
  heavily on implementation-specific behavior since there is little other
  choice. As such, any change is almost certain to break lots of programs,
  in usually superficial but nevertheless important ways. However, if we
  really make the pathname facility more portable, the user community may be
  willing to bear the consequences of these changes.

Cost of Non-Adoption:

  We would be contributing to the perpetuation of the existing fiasco of a
  pathname system.

Benefits:

  The major costs of non-adoption would be avoided.

Aesthetics:

  More code is required, but the code supports a simpler user model.
  Anything that simplifies the user model of pathnames is going to be an
  improvement.

Discussion:

  Some people would rather use lowercase as the canonical case.  The
  decision is essentially arbitrary.  Everywhere else in Common Lisp
  where there is a canonical case, uppercase was chosen.

  It has been proposed that the Common Lisp specification should include
  specifications of the exact behavior of pathnames for several popular
  operating systems, so that multiple implementations for those
  operating systems would be compatible with each other.  This proposal
  does not attempt to do that, only to establish the coherent framework
  within which it would be done.

  In PATHNAME-COMPONENT-CASE:KEYWORD-ARGUMENT, some people want the
  default for :CASE to be :LOCAL instead of :COMMON.  I would have
  written that up too, but I thought five proposals were too many.

∂23-Mar-89  0028	X3J13-mailer 	20 March cs proposal 
Received: from IBM.COM by SAIL.Stanford.EDU with TCP; 23 Mar 89  00:27:44 PST
Date: Wed, 22 Mar 89 15:01:01 PST
From: Thom Linden <baggins@IBM.com>
To: Common Lisp mailing <x3j13@sail.stanford.edu>
Message-ID: <890322.150101.baggins@almvma>
Subject: 20 March cs proposal

I've sent out the latest cs proposal again in LaTex format.
(Sorry, I have no public login and was unable to login to one
 which Gregor offered.

 Sandra, if possible please put a DVI file out on cs.utah.edu again)


I've again tried to incorporate many of the comments received.  The
main features are:

      -- The entire format was revamped!  Appendix A no longer
         exists; everything is in Chapter 2.  The items which are
         'voting' items are denoted by italized sections titled
         PROPOSAL.  All the proposals are numbered, some are
         alternatives to prior proposals (and are marked ALTERNATIVE).
         Anything not within a PROPOSAL section is simply discussion.

         A fringe benefit is the document is only 22 pages.

      -- I've tried to break up proposals which comments indicated
         should be voted upon individually.

      -- Some of the new/revised proposals suggested by comments:

          -- Removing char-code-limit, char-code and code-char
          -- Base-character is now based on
               (upgraded-array-element-type 'standard-char)
          -- A new function, find-external-char which returns
               a character object given a coded character set
               name and index.
          -- Specifing the behavior of with-output-to-string
               if no string is specified and
               make-string-output-stream to produce a stream
               that accepts all characters and returns
               the most specialized string type that accommodates
               the characters actually output.

          -- Various 'too long' names were changed per comments.
               For example, the new keyword argument to open is
               now (simply) :external-code.



Regards,
  Thom

∂23-Mar-89  0127	X3J13-mailer 	20 March cs proposal part 1 of 1    
Received: from IBM.COM by SAIL.Stanford.EDU with TCP; 23 Mar 89  01:25:02 PST
Date: Wed, 22 Mar 89 14:24:58 PST
From: Thom Linden <baggins@IBM.com>
To: Common Lisp mailing <x3j13@sail.stanford.edu>
Message-ID: <890322.142458.baggins@almvma>
Subject: 20 March cs proposal part 1 of 1


\documentstyle{report}     % Specifies the document style.

\pagestyle{headings}

\title{\bf
Extensions to Common LISP to Support International
Character Sets}
\author{
Michael Beckerle\thanks{Gold Hill Computers} \and
Paul Beiser\thanks{Hewlett-Packard} \and
Jerry Duggan\thanks{Hewlett-Packard} \and
Robert Kerns\thanks{Independent consultant} \and
Kevin Layer\thanks{Franz, Inc.} \and
Thom Linden\thanks{IBM Research, Subcommittee Chair} \and
Larry Masinter\thanks{Xerox Research} \and
David Unietis\thanks{Lucid, Inc.}
}
\date{March 20, 1989} % Deleting this command produces today's date.

\begin{document}

\maketitle                 % Produces the title.

\setcounter{secnumdepth}{4}

\setcounter{tocdepth}{4}
\tableofcontents


%----------------------------------------------------------------------
%----------------------------------------------------------------------
\newtheorem{prop}{Proposal}[section]
\newfont{\cltxt}{cmr10}
\newfont{\clkwd}{cmtt10}

\newcommand{\apostrophe}{\clkwd '}
\newcommand{\bq}{\clkwd\symbol{'22}}


%----------------------------------------------------------------------
%----------------------------------------------------------------------
\chapter{Introduction}

This is a proposal to the X3 J13 committee
for both extending and modifying the Common LISP
language definition to provide a standard basis for Common LISP
support of the variety of characters used to represent the
native languages of the international community.

This proposal was created by the Character Subcommittee of X3 J13.
We would like to acknowledge discussions with T. Yuasa and other
members of the JIS Technical Working Group,
comments from members of X3 J13,
and the proposals \cite{ida87},
\cite{linden87}, \cite{kerns87}, and \cite{kurokawa88} for
providing the motivation and direction for these extensions.
As all these documents and discussions were created
expressly for LISP standardization usage,
we have borrowed freely from their ideas as well as the texts
themselves.


\section{Objectives}

The major objectives of this proposal are:
\begin{itemize}
\item To provide a consistent, well-defined scheme allowing support
of both very large character sets and multiple character sets.
\footnote{The distinction between the terms {\em character repertoire}
and {\em coded character set} is made later.  The usage
of the term {\em character set},
avoided after this introduction, encompasses both terms.}

Many software applications are intended for international use, or
have requirements for incorporation of language elements of multiple
native languages within a single application.
Also, many applications require specialized languages including,
for example, scientific and typesetting symbols.
In order
to ensure some portability of these applications, data expressed in
a mixture of these
languages must be treated uniformly by the
software language.

All character and string manipulations should operate uniformly,
regardless of the character set(s) of the character objects.
This applies to array indexing, readtable definitions, read
symbol construction and I/O operations.


\item To ensure efficient performance of string and character
operations.

Many native
languages, such as Japanese and Chinese, use character
sets which contain more characters than the Latin alphabet.
Supporting larger sized character sets frequently means employing
larger data fields to uniquely encode each character.
Common LISP implementations using
larger sized character sets can
incur performance penalties in terms
of space, time, or both.

The use of large and/or multiple character sets by an
implementation
implies the need for a more complex character type representation.
Given a more complex character representation, the efficiency
of language operations on characters (e.g. string operations)
could be affected.

\item To assure forward compatibility of the proposed model
and definition with existing Common LISP implementations.

Developers should not be required to re-write large amounts of either
LISP code or data representations in order to apply the proposed
changes to existing implementations.
The proposed changes should provide an easy
portability path for existing code to many possible implementations.
\end{itemize}

There are a number of issues, some under the general rubric of
internationalization, which this proposal does {\em not} cover.
Among these issues are:
\begin{itemize}
\item Time and date formats
\item Monetary formats
\item Numeric punctuation
\item Fonts
\item Lexicographic orderings
\item Right-to-left and bidirectional languages
\end{itemize}

%----------------------------------------------------------------------
%----------------------------------------------------------------------
%----------------------------------------------------------------------
%----------------------------------------------------------------------
\chapter{Overview}

We use several terms within this document which
are new in the context of Common LISP.
Definitions for the following prominent
terms are provided for the reader's convenience.

A {\em character repertoire} defines a collection of characters
independent of their specific rendered image or font.  This
corresponds to the mathematical notion of a {\em set}
\footnote{We avoid the term {\em character set} as it has been
(over)used in the context of character repertoire as well
as in the context of coded character set.}.
Character
repertoires are specified independent of coding and their characters
are only identified with a unique {\em character label},
a graphic symbol, and
a character description.

A {\em coded character set} is a character repertoire plus
an {\em encoding} providing a unique mapping between each character
and a number which serves as the character representation.
There are numerous internationally standardized coded character
sets; for example, \cite{iso8859/1} and \cite{iso646}.

A character may be included in one or more character repertoires.
Similarly, a character may be included in one or more
coded character sets.  For example, the Latin letter "A" is contained
in the coded character set standards: ISO 8859/1, ISO 8859/2,
ISO 6937/2, and others.

To universally identify each character, we define a unique
collection of repertoires called {\em character
registries} as a partitioning of all characters.
That is, each character is included
in one and only one character registry.

In Common LISP a {\em character} data object is identified by its
{\em character code}, a unique numerical code.
Each character code is composed from
a character registry and a character label.

Character data objects which are classified as {\em graphic},
or displayable, are each associated with a {\em glyph}.  The
glyph is the visual representation of the character.
Character data objects which are not graphic are classified
as {\em control}.


The primary purpose of introducing these terms is to provide a
consistent naming to Common LISP concepts which are related
to those found in ISO standardization of coded
character sets.
\footnote{The bibliography includes several relevant ISO
coded character set standards.}
They also serve as a demarcation between these
standardization activities.  For example, while Common LISP is free to
define unique manipulation facilities for characters, registries
and coded character sets, it should
not define standard coded character sets nor standard character
registries.

A secondary purpose is to detach the language specification from
underlying hardware representation.  From a language
specification viewpoint it is inconsequential whether
characters occupy one or more (8-bit) bytes or whether
a Common LISP implementation's
internal representation for characters is distinct from or identical
to any of the numerous
external representations (for example, the text interchange
representation \cite{iso6937/2}).
We specifically do not propose any standard coded character sets.

A final purpose is to serve as a basis for terminology within the
standard language specification.

\begin{prop}
The terminology introduced in this proposal will be included
in the language specification at the discretion of the editor.
\end{prop}


%----------------------------------------------------------------------
\section{Character Identity}

Characters are uniquely distinguished by their codes,
which are drawn from the set of
non-negative integers.  That is, within Common LISP
a unique numerical code
is assigned to each semantically different character.

It is important to separate the notion of glyph from the notion of
character data object when defining a scheme under which issues of
identity can be rigorously decided by a computer language.  Glyphs are
the visual aspects of characters, writable on surfaces, and sometimes
called 'graphics'.  A language specification valid for more than a
narrow range of systems can only make assumptions about the existence
of {\em abstract} glyphs (for example, the Latin letter A) and not about
glyph variants (for example, the italicized Latin letter {\em A})
or characteristics of display devices.

The notion of attributes of character
objects within Common LISP has proven to be either not used or
not portable.  The essential aspect of the following proposals is
to what extent attributes continue to be supported by the
language specifications.

\begin{prop}[Alternative A]
 Remove all discussion of attributes from
 the language specification.  Add the following discussion:
\begin{quote}
Earlier versions of Common LISP incorporated {\em font} and
{\em bits} as attributes of character objects.  These and other
supported attributes are considered implementation-defined
attributes and if supported by an implementation effect the
action of selected functions.
\end{quote}
 All types, constants and functions
 dealing with the {\em bits} and {\em font} attributes are either
 removed or modified as follows:
\begin{itemize}
\item Modify {\clkwd char-=}: If two characters differ in any
implementation-defined attributes, then they are not {\clkwd char-=}.
\item Modify {\clkwd char-<}: If two characters have identical
  implementation-defined attributes, then their ordering by
  {\clkwd char}$<$ is consistent with the numerical ordering by the
  predicate $<$ on
  their code. (Similarly for {\clkwd char}$>$,
  {\clkwd char}$>=$ and {\clkwd char}$<=$.)
\item Modify {\clkwd char-equal}:
The effect, if any, on {\clkwd char-equal} of each
  implementation-defined attribute has to be specified as part of
  the definition of that attribute (and similarly for
  {\clkwd char-not-equal, char-lessp, char-greaterp,
   char-not-greaterp, char-not-lessp}).
\item Modify {\clkwd char-upcase} and {\clkwd char-downcase}:
The effect of {\clkwd char-upcase} and {\clkwd char-downcase}
  is to preserve implementation-defined attributes.
\item  Modify {\clkwd read}: It is implementation dependent which
  attributes are removed from symbol names.
  It is implementation dependent which attributes are removed
  from characters within double quotes.
\item  Modify {\clkwd intern}: It is implementation dependent,
but consistent with the {\clkwd read} function,
which implementation-defined attributes are removed.
\item  Modify {\clkwd digit-char}: remove the optional {\em font}
argument.
\item  Modify {\clkwd code-char}: remove the optional {\em font}
and {\em bits} arguments.
\item Remove {\clkwd char-font-limit}
\item Remove {\clkwd char-bits-limit}
\item Remove {\clkwd int-char}
\item Remove {\clkwd char-int}
\item Remove {\clkwd char-bits}
\item Remove {\clkwd char-font}
\item Remove {\clkwd make-char}
\item Remove {\clkwd char-control-bit}
\item Remove {\clkwd char-meta-bit}
\item Remove {\clkwd char-super-bit}
\item Remove {\clkwd char-hyper-bit}
\item Remove {\clkwd char-bit}
\item Remove {\clkwd set-char-bit}
\item Redefine {\clkwd string-char} as implementation defined
as either {\clkwd base-character} or {\clkwd character}.
\item Modify readtable: If implementation-defined attributes
are supported, an implementation need not (but may) allow
for such characters to have syntax descriptions in the readtable.
Otherwise, all characters are representable in the readtable.
\end{itemize}
\end{prop}

\begin{prop}[Alternative B]
 This is identical to all of Alternative A (above) except that
 the function {\clkwd char-int} is retained for hashing purposes.
 {\clkwd char-int} returns a non-negative integer encoding the
 character object.  The manner in which the integer is computed
 is implementation dependent. In contrast to {\clkwd sxhash},
 the result is not guaranteed independent of the particular
 "incarnation" or "core image".
\end{prop}

With the elimination of {\em font} and {\em bits} from the
specification the usefulness of {\clkwd char-code} and {\clkwd
code-char} is diminished.  They are no longer needed for constructing
characters.
The portable mechanisms for hashing are provided by
{\clkwd char-int} and {\clkwd sxhash}.

In addition, using {\clkwd char-code-limit} to iterate over
characters is extremely inefficient in implementations that
support large or user-defined repertoires.

\begin{prop}[Alternative C]
 This an amendment to Alternative B (above).
\begin{itemize}
\item Remove {\clkwd char-code-limit}
\item Remove {\clkwd char-code}
\item Remove {\clkwd code-char}
\end{itemize}
\end{prop}

%----------------------------------------------------------------------
\section{Standard and Semi-Standard Characters}

The standard characters are the 96 characters used in the Common LISP
definition {\bf or their equivalents}.

This was the Common LISP \cite{steele84} definition, but
{\em equivalents} is a vague term.

The standard characters are not defined by their glyphs, but by their
roles within the language.  There are two aspects to the roles of the
standard characters: one is their role in reader and format control
string syntax; the second is their role as components of the names of
all Common LISP
functions, macros, constants, and global variables.  As
long as an implementation chooses 96 glyphs
and treats those 96 in a manner consistent with
the language's specification for the standard characters (e.g.
the naming of functions), it doesn't matter what glyphs the I/O
hardware uses to represent those characters: they are the standard
characters.  Any program or
data text written wholly in those characters
is portable through simple code conversion.
\footnote{For example, the currency glyph, \$ , might be replaced
uniformly by the currency glyph available on a particular display.}

Additional mechanisms,
such as in \cite{kurokawa88}, which support establishment of
equivalency between otherwise distinct characters are not excluded by
this proposal.
\footnote{We believe this is an important issue but it requires
additional implementation experience.  We also encourage
new proposals from JIS and ISO LISP Working Groups on this issue.}


\begin{prop}
The discussion of standard characters is
replaced by the following:

  Common LISP requires all implementations to support a {\em standard}
  character subrepertoire.
  The Common LISP
  standard character subrepertoire consists of
  a newline \#$\backslash${\clkwd Newline}, the
  graphic space character \#$\backslash${\clkwd Space},
  and the following additional
  ninety-four graphic characters or their equivalents:
\footnote{\cltxt \#$\backslash${\clkwd Space}
and \#$\backslash${\clkwd Newline} are omitted.
graphic labels and descriptions are from ISO 6937/2.
The first letter of the graphic Id categorizes the
character as follows: L - Latin, N - Numeric, S - Special
.}

{\small \begin{tabular}{||l|c|l||l|c|l||}    \hline
  Id     &    Glyph    &  Name or description
& Id     &    Glyph    &  Name or description
\\ \hline
  LA01  &  a  &  small a
& ND01  &  1  &  digit 1
\\ \hline
  LA02  &  A  &  capital A
& ND02  &  2  &  digit 2
\\ \hline
  LB01  &  b  &  small b
& ND03  &  3  &  digit 3
\\ \hline
  LB02  &  B  &  capital B
& ND04  &  4  &  digit 4
\\ \hline
  LC01  &  c  &  small c
& ND05  &  5  &  digit 5
\\ \hline
  LC02  &  C  &  capital C
& ND06  &  6  &  digit 6
\\ \hline
  LD01  &  d  &  small d
& ND07  &  7  &  digit 7
\\ \hline
  LD02  &  D  &  capital D
& ND08  &  8  &  digit 8
\\ \hline
  LE01  &  e  &  small e
& ND09  &  9  &  digit 9
\\ \hline
  LE02  &  E  &  capital E
& ND10  &  0  &  digit 0
\\ \hline
  LF01  &  f  &  small f
& SC03  &  \$    &  dollar sign
\\ \hline
  LF02  &  F  &  capital F
& SP02  &  !     &  exclamation mark
\\ \hline
  LG01  &  g  &  small g
& SP04  &  "     &  quotation mark
\\ \hline
  LG02  &  G  &  capital G
& SP05  &  \apostrophe     &  apostrophe
\\ \hline
  LH01  &  h  &  small h
& SP06  &  (     &  left parenthesis
\\ \hline
  LH02  &  H  &  capital H
& SP07  &  )     &  right parenthesis
\\ \hline
  LI01  &  i  &  small i
& SP08  &  ,     &  comma
\\ \hline
  LI02  &  I  &  capital I
& SP09  &  \_    &  low line
\\ \hline
  LJ01  &  j  &  small j
& SP10  &  -     &  hyphen or minus sign
\\ \hline
  LJ02  &  J  &  capital J
& SP11  &  .     &  full stop, period
\\ \hline
  LK01  &  k  &  small k
& SP12  &  /     &  solidus
\\ \hline
  LK02  &  K  &  capital K
& SP13  &  :     &  colon
\\ \hline
  LL01  &  l  &  small l
& SP14  &  ;     &  semicolon
\\ \hline
  LL02  &  L  &  capital L
& SP15  &  ?     &  question mark
\\ \hline
  LM01  &  m  &  small m
& SA01  &  +     &  plus sign
\\ \hline
  LM02  &  M  &  capital M
& SA03  &  $<$   &  less-than sign
\\ \hline
  LN01  &  n  &  small n
& SA04  &  =   &  equals sign
\\ \hline
  LN02  &  N  &  capital N
& SA05  &  $>$   &  greater-than sign
\\ \hline
  LO01  &  o  &  small o
& SM01  &  \#    &  number sign
\\ \hline
  LO02  &  O  &  capital O
& SM02  &  \%    &  percent sign
\\ \hline
  LP01  &  p  &  small p
& SM03  &  \&    &  ampersand
\\ \hline
  LP02  &  P  &  capital P
& SM04  &  *     &  asterisk
\\ \hline
  LQ01  &  q  &  small q
& SM05  &  @     &  commercial at
\\ \hline
  LQ02  &  Q  &  capital Q
& SM06  &  [     &  left square bracket
\\ \hline
  LR01  &  r  &  small r
& SM07  &  $\backslash$   &  reverse solidus
\\ \hline
  LR02  &  R  &  capital R
& SM08  &  ]     &  right square bracket
\\ \hline
  LS01  &  s  &  small s
& SM11  &  \{    &  left curly bracket
\\ \hline
  LS02  &  S  &  capital S
& SM13  &  $|$     &  vertical bar
\\ \hline
  LT01  &  t  &  small t
& SM14  &  \}    &  right curly bracket
\\ \hline
  LT02  &  T  &  capital T
& SD13  &  \bq   &  grave accent
\\ \hline
  LU01  &  u  &  small u
& SD15  &  $\hat{ }$  &  circumflex accent
\\ \hline
  LU02  &  U  &  capital U
& SD19  &  $\tilde{ }$ &  tilde
\\ \hline
  LV01  &  v  &  small v
& & &
\\ \hline
  LV02  &  V  &  capital V
& & &
\\ \hline
  LW01  &  w  &  small w
& & &
\\ \hline
  LW02  &  W  &  capital W
& & &
\\ \hline
  LX01  &  x  &  small x
& & &
\\ \hline
  LX02  &  X  &  capital X
& & &
\\ \hline
  LY01  &  y  &  small y
& & &
\\ \hline
  LY02  &  Y  &  capital Y
& & &
\\ \hline
  LZ01  &  z  &  small z
& & &
\\ \hline
  LZ02  &  Z  &  capital Z
& & &
\\
\hline
\end{tabular} }

\end{prop}

The definition of semi-standard characters has been of minimum
practical use since implementations may or may not support any
of these characters.  The essential feature is that, when
supported, they have a predictable treatment by the reader.

\begin{prop}
Remove all discussion of semi-standard characters.
Add that in implementations supporting control characters other than
\#$\backslash${\clkwd Newline}, the {\clkwd read} function
is required to treat those as
whitespace characters.
\end{prop}

%----------------------------------------------------------------------
\section{Hierarchy of Types}

Providing support for extensive character repertoires may
impact Common LISP implementation performance in terms
of space, time, or both.
\footnote{This does not apply to all implementations.
Unique hardware support and user community requirements need to
be taken into consideration.}
In particular, many existing
implementations support variants of the ISO 8859/1 standard.
Supporting large
repertoires argues for a multi-byte internal representation
for each character, even if an application primarily (or exclusively)
uses the ISO 8859/1 characters.

This proposal extends the definition of the character and string
type hierarchy to allow specialized subtypes
of character and string.  An implementation is free to associate
compact internal representation tailored to each subtype.
The {\clkwd string} type specifier, when used for object
creation, for example in {\clkwd make-sequence},
is defined to mean the most general string subtype supported
by the implementation (similarly for the {\clkwd simple-string}
type specifier).  This definition emphasizes portability
of existing Common LISP applications to international
character environments over performance.  Applications emphasizing
efficiency of text processing in non-international environments
will require some modification to utilize subtypes with
compact internal representations.

It has been suggested that either a single type is
sufficient to support international characters,
or that a hierarchy of types could be used, in a manner
transparent to the user.  A desire to provide flexibility which
encourages implementations to support international
characters without compromising application efficiency
led us to accept the need for more than one type.
We believe that these choices reflect a minimal
modification of this aspect of the type system, and that
exposing the types for string and character construction while
requiring uniform treatment for characters otherwise
is the most reasonable approach.


\subsection{Character Type}

\begin{prop}
  Define {\clkwd base-character} as {\clkwd
(upgraded-array-element-type 'standard-char)}.
Characters of type {\clkwd base-character} are referred to as
{\em base characters}.  Characters of type {\clkwd
(and character (not base-character))}
are referred to as {\em extended characters}.
\end{prop}

This establishes the relationship between the string encoding and
array upgrading strategies of the implementation and
the important character types.

An implementation may support additional subtypes of {\clkwd character}
which may or may not be supertypes of {\clkwd base-character}.
In addition, an implementation may define {\clkwd base-character}
as equivalent to {\clkwd character}.

The base characters are
distinguished in the following respects:
\begin{itemize}
\item
The standard characters are a subrepertoire of the base characters.
\item
The selection of base characters which are not standard characters
is implementation defined.
\item
Only members of the base character repertoire
can be elements of a base string.
\item
No upper bound is specified for the number of glyphs in the base
character repertoire--that
is implementation dependent.  The lower bound is 96, the
number of standard characters defined for Common LISP.
\footnote{Or, in contrast, the base repertoire may include all
implementation supported characters.}
\end{itemize}

The distinction of base characters is largely a pragmatic
choice.  It permits efficient handling of common situations, may
be privileged for host system I/O, and can serve as an
intermediate basis for portability, less general than the standard
characters, but possibly more useful across a narrower range of
implementations.

Many computers have some "base" character representation which
is a function of hardware instructions for dealing with characters,
as well as the organization of the file system.  The base character
representation is likely to be the smallest transaction unit permitted
for text file and terminal I/O operations.  On a system with a record
based I/O paradigm, the base character representation is likely to
be the smallest record quantum.  On many computer systems,
this representation is a byte.

However,
the proposal emphasizes that whether a character is "base" to
Common LISP depends on the way that an implementation represents
strings, and not any other properties of the implementation or the
host operating system.  Imagine two implementations, one of which
encodes all strings as 16-bit characters, and another which has
two kinds of strings: 8-bit strings and 16-bit strings.  In the
first implementation, the {\clkwd base-character} is
{\clkwd character}: there's only one kind of string.  In the
second implementation, the {\clkwd base-character} would be those
that could be stored in an 8-bit string, and it would be a proper
sub-type of {\clkwd character}.


\subsection{String Type}

\begin{prop}
The {\clkwd string} type
is defined as
a union type.  More precisely, a string
is a specialized vector whose elements are of type
{\clkwd character} or a subtype of {\clkwd character}.
{\clkwd string} used as a type specifier for object creation
means {\clkwd (vector character)}.
\end{prop}

\begin{prop}
The following string
subtypes are
distinguished with standardized names.
\begin{itemize}
\item {\clkwd base-string} is equivalent to {\clkwd (vector
base-character)}.
Strings of type {\clkwd base-string} are referred to as {\em base
strings}.  Strings which are not base strings are referred to
as {\em extended strings}.
\item {\clkwd general-string} is equivalent to {\clkwd (vector
character)}.
\item Both are valid as type specifiers that abbreviate.
\end{itemize}

During reader
construction of symbols, if all the characters
in the symbol's name are of type {\clkwd base-character},
then the name of the symbol may be stored as a base string.
Otherwise it will be stored as an extended string.
\end{prop}

\begin{prop}
Define {\clkwd simple-string} as a union type.
A simple
string is a specialized simple vector whose elements are of type
{\clkwd character} or a subtype of character.
{\clkwd simple-string} used as a type specifier for object creation
means {\clkwd (simple-array character ({\em size}))}.
\end{prop}

\begin{prop}
The following simple string
subtypes are
distinguished with standardized names:
\begin{itemize}
\item {\clkwd simple-base-string} is equivalent to {\clkwd
(simple-array base-character (*)). simple-base-string} is a subtype
of {\clkwd base-string}.
\item {\clkwd simple-general-string} is equivalent to {\clkwd
(simple-array character (*)). simple-general-string} is a subtype
of {\clkwd general-string}.
\item Both are valid as type specifiers that abbreviate.
\end{itemize}
\end{prop}

A base string is the most efficient string which can hold
the standard characters.
A {\clkwd general-string}
can contain any implementation supported base or extended characters,
in any mixture.

All Common LISP functions defined to operate on strings treat
base and extended strings uniformly with the following
caveat: for any function which inserts a character into a string, it
is an error to insert an extended character
into a base string.
\footnote{An implementation may, optionally, provide automatic
coercion to an extended string.}

An implementation may support string subtypes in addition
to {\clkwd base-string} and
{\clkwd general-string}.
For example, a hypothetical
implementation supporting Arabic and Cyrillic characters
might provide as extended characters:
\begin{itemize}
\item {\clkwd general-string} -- may contain Arabic, Cyrillic or
base characters in any mixture.
\item {\clkwd region-specialized-string} -- may contain installation
selected repertoire (Arabic/Cyrillic) or base characters in any
mixture.
\item {\clkwd base-string} -- may contain base characters
\end{itemize}
Though, clearly, portability of applications using
{\clkwd region-specialized-string} is limited, a performance
advantage might argue for its use.
\footnote{{\clkwd region-specialized-string} is used here for
illustration only; it is not being proposed as a standardized
string subtype.}

Alternatively,
an implementation
supporting a large base character repertoire
including, say, Japanese Kanji may define
{\clkwd base-character}
as equivalent to {\clkwd character}.

We expect that applications sensitive to the performance
of character handling in some host environments will
utilize the string subtypes to provide performance
improvement.  Applications with emphasis on international
portability will likely utilize only {\clkwd general-string}s.

The base string type allows for more compact representation of strings
of base characters, which are likely to predominate in any system.
Note that in any particular implementation the base characters
need not be the
most compactly representable, since others might have
a smaller repertoire.
However, in most implementations base strings are
likely to be more space efficient than extended strings.

\begin{prop}
Extend the {\clkwd make-string} function to allow an
{\clkwd element-type} keyword argument:
\begin{itemize}
\item {\clkwd make-string} {\em size}
{\clkwd \&key :initial-element :element-type} [Function]

This returns a simple string of length {\em size}, each
of whose characters has been initialized to the
{\clkwd :initial-element} argument.  If an {\clkwd :initial-element}
argument is not specified, then the string will be
initialized in an implementation-dependent way.  The
{\clkwd :element-type} argument names the type of the elements
of the string; a string is constructed of the most specialized
type that can accommodate elements of the given type.  If
{\clkwd :element-type} is omitted, the type {\clkwd character}
is the default.
\end{itemize}
\end{prop}

%----------------------------------------------------------------------
\section{Character Naming}

A Common LISP program should be able to name, compose and decompose
characters in a uniform, portable manner, independent of any
underlying representation.  One possible composition is by
the pair $<$ coded character set standard, decimal representation $>$
\footnote{This syntax is for illustration only and is not being
proposed.}.
Thus, for example, one might compose the Latin 'A' with the pair
$<$ ISO8859/2-1987, 65 $>$,
$<$ ISO8859/6-1987, 65 $>$, or
$<$ ISO646-1983, 65 $>$, etc..  The difficulty here is two-fold.
First, there are several ways to compose the same character and
second, there may be multiple answers to
the question: {\em To what coded character set
does character object x belong?}\footnote{Even
worse, the answer might change yearly.}
The identical problems occur if the pair
$<$ character repertoire standard, decimal representation $>$ is used.
\footnote{Existing ISO repertoires seem to be defined exclusively
in the context of coded character sets and not as standards
in their own right.}

The concept of character registry is introduced by this proposal
to resolve the problem of character naming, composition and
decomposition.
Each character is universally defined by the
pair $<$ character registry name, character label $>$. For this
to be a portable definition, it must have a standard meaning.
Thus we propose the formation of an ISO Working Group to
define an international
{\em Character Registry Standard}.
At this writing there is no existing Character Registry Standard nor
ISO Working Group organized to define such a standard.
\footnote{It is the intention of X3 J13 to promote and adopt
an eventual ANSI or ISO Character Registry Standard.  In particular, we
acknowledge that X3 J13 is {\em not} the appropriate forum to
define the standard.  We believe
it is a required component of all programming languages
providing support for international characters.}

\begin{prop}
Common LISP character codes are composed from a character registry and
a character label.  The convention by which a character label and
character registry compose a character code is implementation
dependent.
\end{prop}

The naming and content of the standard character registries
is left unspecified by this proposal.
\footnote{The only constraint is that character registries and
labels be named using only the Latin capital letters A-Z and
digits 0-9.}
Below are some candidate character registry names:
\begin{itemize}
\item Arabic
\item Armenian
\item Bopomofo
\item Control   (meaning the collection of standard text communication
control codes)
\item Cyrillic
\item Georgian
\item Greek
\item Hangul
\item Hebrew
\item Hiragana
\item JapanesePunctuation
\item Kanji
\item Katakana
\item Latin
\item LatinPunctuation
\item Mathematical
\item Pattern
\item Phonetic
\item Technical
\end{itemize}
The list above is provided as a starting point for discussion
and is not intended to be representative
nor exhaustive.  The Common LISP language definition does not
depend on these names nor any specific content (for example:
Where should the plus sign appear?).  It is application
programs which require a reliable definition of the
registry names and their constituents.  The Common LISP language
definition imposes the framework for constructing and manipulating
character objects.

\begin{prop}
Standardized Character Registries are fixed;
an implementation may not extend a standard registry's
constituent set of characters beyond the
standard definition.

An implementation may provide support for all or part of any
character registry
and may provide new character registries which include characters
having unique semantics (i.e. not defined in any standard
character registry).
Implementation registries must be uniquely
named using only Latin capital letters A-Z and digits 0-9.

An implementation must document the registries it supports.
For each registry supported the documentation must include
at least the following:
\begin{itemize}
\item Character Labels,
Glyphs, and Descriptions.  Character labels must be uniquely
named using only Latin capital letters A-Z and digits 0-9.
\item Reader Canonicalization.
\footnote{Any mechanisms by which the {\clkwd read} function treats
distinct characters as equivalent.}
\item Effect of character predicates. In particular,
\begin{itemize}
\item {\clkwd alpha-char-p}
\item {\clkwd lower-case-p}
\item {\clkwd upper-case-p}
\item {\clkwd both-case-p}
\item {\clkwd graphic-char-p}
\item {\clkwd alphanumericp}
\end{itemize}
\item Interaction with File I/O.  In particular, the
coded character sets
\footnote{For example, ISO8859/1-1987.} and
external encoding schemes
supported are documented.
\end{itemize}
\end{prop}

We introduce new functions to
compose and decompose character objects.  We also extend the
{\clkwd characterp} predicate to
support testing
membership of a character in a given character repertoire.
\footnote{
For example,
testing membership in the Japanese Katakana character repertoire.
}
A global variable {\clkwd *all-character-registry-names*}
is added to
allow application determination of
implementation supported character registries.

\begin{prop}
Add the type specifier and (modified) type predicate:
\begin{itemize}
\item {\clkwd (character {\em repertoire})}

This denotes a character type specialized to members of the
specified repertoire.  {\em Repertoire} may be {\clkwd :base}
or {\clkwd :standard} or any supported character repertoire
name (a keyword symbol), or a list of names.

{\clkwd (character :base)} is equivalent to {\clkwd base-character}
and
{\clkwd (character :standard)} is equivalent to {\clkwd standard-char}
\item {\clkwd (characterp {\em object} \&optional
{\em repertoire})}

If {\em repertoire} is omitted, {\clkwd characterp} is true if
{\em object} is a character object, and otherwise is false.  If
a {\em repertoire} argument is specified, {\clkwd characterp}
is true if {\em object} is a character object and a member
of the specified repertoire, and otherwise is false.  {\em Repertoire}
may be any supported character repertoire name (a keyword symbol)
or the names {\clkwd :base} or {\clkwd :standard}.
{\clkwd (characterp x :standard)} is equivalent to
{\clkwd (standard-char-p x)}.
{\clkwd (characterp x :base)} is true if x is a member of the
base character repertoire.


\end{itemize}

\end{prop}

\begin{prop}
Add the following variable and functions:
\begin{itemize}
\item {\clkwd *all-character-registry-names*} {\em  [Variable]}

The value of {\clkwd *all-character-registry-names*} is a list
of all character repertoire names (keyword symbols) supported by
the implementation.
\item {\clkwd char-label} {\em char [Function]}

{\clkwd char-label} returns a string representing the character
label of {\em char}.  It is an error if the argument is
not a character object.
\item {\clkwd char-registry-name} {\em char [Function]}

{\clkwd char-registry-name} returns a string representing the character
registry to which {\em char} belongs. It is an error if the
argument is not a character object.
\item {\clkwd find-char} {\em registry label [Function]}

{\clkwd find-char} returns a character object.  The arguments
{\em registry} and {\em label} are names (keyword symbols) of
a character registry and label.  {\em label} uniquely
identifies a character within the character registry named
{\em registry}.  If the implementation does not support the
specified character, {\clkwd nil} is returned.
\end{itemize}

\end{prop}

\begin{prop}
Character
names accepted and constructed by {\clkwd char-name, name-char,
and read} are extended to include character registry names of
the form {\em registry:label}.
\end{prop}

%----------------------------------------------------------------------
\section{Streams and System I/O}

A lot of the work of ensuring that a
Common LISP implementation operates correctly in a
multiple coded character set environment must be performed by
the I/O interface.
The system I/O interface, abstracted in
Common LISP as streams, is responsible
for ensuring that text input from outside LISP is properly mapped
into character objects internally, and that the inverse mapping
is performed on output.  It is beyond the scope of a language
definition to specify the details of this operation, but options
are specified which allow runtime indication from the user as to
what coded character sets a stream uses, and how the mappings
should be done.  It is expected that implementations will provide
reasonable defaults and invocation options to accommodate desired use
at an installation.

There are often multiple
coded character sets supportable on a
computer, through the use of special display and entry hardware, which
are varying interpretations of the basic system character
representation.  For example, ISO 8859/1 and ISO 6937/2 are two
different interpretations of the same 1-byte code representations.
Many countries have their own glyph-to-code mappings for 1-byte
character codes addressing the special requirements of national
languages.  Differentiating between these, without reference to
display hardware, is a matter of convention, since they all use the
same set of code representations.  When a single byte is not enough,
two or more bytes are sometimes used for character encoding.  This
makes character handling even more difficult on machines where the
natural representation size is a byte, since not only is the semantic
value of a character code a matter of convention, which may vary
within the same computing system, but so is the identification of a
set of bits as a complete character code.

Given that multiple coded character sets exist, it is useful
to provide portable mechanisms based on their definitions.

\begin{prop}
Add the following functions:
\begin{itemize}
\item {\clkwd char-external-code} {\em char name [Function]}

{\clkwd char-external-code} returns the non-negative integer
representing the encoding of the character {\em char} in the
coded character set named by {\em name}, a keyword symbol.  If
the implementation does not support the specified coded
character set, {\clkwd nil} is returned.  If the named
coded character set does not contain the character,
{\clkwd nil} is returned.
\item {\clkwd find-external-char} {\em name index [Function]}

{\clkwd find-external-char} returns a character object.
The argument {\em index} is a non-negative integer
representing the encoding of a character in the
coded character set named by {\em name}, a keyword symbol.  If
the implementation does not support the specified coded
character set, {\clkwd nil} is returned.  If the named
coded character set does not contain the character,
{\clkwd nil} is returned.
\end{itemize}
\end{prop}

An implementation supporting multiple coded character sets
must allow for the external
representation of characters to be separately (and perhaps
multiply) specified to {\clkwd open},
since there can be circumstances under
which more than one external representation for characters
is in use, or more than one coded character set
is mixed together in an
external representation convention.

Which coded character sets and encoding schemes
are supported by the overall computing system and the
details of the mapping of glyphs to characters
to character codes are
left unspecified by Common LISP.


\begin{prop}
Add the additional keyword argument to {\clkwd open}:
\begin{itemize}
\item {\clkwd :external-code}
which
specifies a name, or list of names (keyword symbols)
indicating an implementation recognized scheme for
representing 1 or more coded character sets with non-homogeneous codes.

The default value is {\clkwd :default} and is
implementation defined but must include the
base characters.

As many coded character set names must be provided as the
implementation requires for that external coding convention.

Coded character set names must
include the full reference number and approval year. For example,
:ISO8859P1V1987 and :ISO6937P2V1983.
All implementation recognized schemes are formed from
the Latin uppercase A-Z and digit 0-9 characters.
\end{itemize}

This argument is provided for input, output, and
bidirectional streams.
It is an error to try to write a character other than a
member of the specified coded character sets
to a stream.  (This excludes the
\#$\backslash${\clkwd Newline} character.
Implementations must provide appropriate line division behavior
for all character streams.)
\end{prop}

The existing default for the {\clkwd :element-type} argument of
{\clkwd open} is {\clkwd string-char}.  This is no longer appropriate
given the diminished use of {\clkwd string-char} within the
standard specification.

\begin{prop}
Modify the {\clkwd :element-type} argument to {\clkwd open} as follows:
\begin{itemize}
\item Add {\clkwd base-character} as a valid type.
\item Remove {\clkwd string-char} as a valid type.
\end{itemize}
\end{prop}

The following alternative is consistent with the general
premise that portability is emphasized over efficiency.

\begin{prop} (Alternative A)
The default for the {\clkwd :element-type} argument of {\clkwd open}
is {\clkwd character}.
\end{prop}

The following alternative (B), allows implementations to match
the behavior of {\clkwd open} to the expected behavior of
their file systems.

\begin{prop} (Alternative B)
The default for the {\clkwd :element-type} argument of {\clkwd open}
is implementation defined as either {\clkwd base-character}
or {\clkwd character}.
\end{prop}


\begin{prop}
Modify the following functions:
\begin{itemize}
\item {\clkwd with-output-to-string} if no string argument is
provided, produces a stream that accepts all characters and returns
a string of the most specialized type
that accommodates the characters that were actually output.
\item {\clkwd make-string-output-stream}
produces a stream that accepts all characters and returns
(via {\clkwd get-output-stream-string})
a string of the most specialized type
that accommodates the characters that were actually output.
\end{itemize}
\end{prop}


In addition to supporting conversion at the system interface, the
language must allow user programs to determine how much space data
objects will require when output in whichever external representations
are available.

This function is necessary
to determine if strings can be written to fixed length
fields in databases.  Note that this
function does not
address the problem of calculating
screen width of strings printed in proportional fonts.

\begin{prop}
Add the following function:
\begin{itemize}
\item {\clkwd string-encoded-length} {\em object}
{\clkwd \&optional} {\em output-stream} [Function]

{\clkwd string-encoded-length} returns the number of
implementation defined units required for the object on the
output stream.  If not applicable to the output stream, the
function returns {\clkwd nil}.  This number
corresponds to the current state of the stream and may change if
there has been intervening output.  If the
output stream is not specified {\clkwd *standard-output*} is
the default.
\end{itemize}
\end{prop}



%----------------------------------------------------------------------
\section{Miscellaneous}

In the process of creating this document, some comments were found
within CLtL which seem appropriate to modify independently of
the other proposals mentioned previously.  For each, we identify
the existing statement of CLtL and the recommended change.

%----------------------------------------------------------------------
%----------------------------------------------------------------------

\newcommand{\edithead}{\begin{tabular}{l p{3.95in}}
  \multicolumn{2}{l} }

\newcommand{\csdag}{\bf$\Rightarrow$\ddag}

\newcommand{\editstart}{}

\newcommand{\editend}{\\ & \end{tabular}}

%----------------------------------------------------------------------
%----------------------------------------------------------------------

%----------------------------------------------------------------------

\begin{prop}

\edithead {\csdag (p12) Chapter 2 Data Types}
\editstart
\\ \bf replace &
\cltxt
   provides for a
   rich character set, including ways to represent characters of various
   type styles.
\\ \bf with &
\cltxt
   provides support for international language characters as well
   as characters used in specialized arenas, eg. mathematics.
\editend
\end{prop}


\begin{prop}

\edithead {\csdag (p25) Chapter 2 Symbols}
\editstart
\\ \bf replace &
\cltxt
  A symbol may have uppercase letters, lowercase letters, or
  both in its print name.
\\ \bf with &
\cltxt
  A symbol may have characters from any supported character
  repertoire (except control characters) in its print name.
\editend
\end{prop}

\begin{prop}

\edithead {\csdag (p163) Chapter 10 Symbols}
\editstart
\\ \bf replace &
\cltxt
  It is ordinarily not permitted to alter a symbol's print name.
\\ \bf with &
\cltxt
  It is an error to alter a symbol's print name.
\editend
\end{prop}

\begin{prop}

\edithead {\csdag (p168) Chapter 10 The Print Name}
\editstart
\\ \bf replace &
\cltxt
  It is an extremely bad idea to modify a string being used
  as the print name of a symbol.
\\ \bf with &
\cltxt
  It is an error to modify a string being used
  as the print name of a symbol.
\editend
\end{prop}


\begin{prop}

\edithead {\csdag (p249,make-sequence) Chapter 14 Simple Sequence
Functions}
\editstart
\\ \bf append &
\cltxt
  If type {\clkwd string} is specified, the result is
  equivalent to {\clkwd make-string}.
\editend
\end{prop}

%----------------------------------------------------------------------
%----------------------------------------------------------------------
%----------------------------------------------------------------------
\begin{thebibliography}{wwwwwwww 99}


\bibitem[Ida87]{ida87} M. Ida, et al.,
{\em
JEIDA Common LISP Committee Proposal on Embedding Multi-Byte Characters
},
ANSI X3J13 document 87-022, (1987).

\bibitem[ISO 646]{iso646} ISO,
{\em
Information processing -- ISO 7-bit coded character set
for information interchange
},
ISO (1983).

\bibitem[ISO 4873]{iso4873} ISO,
{\em
Information processing -- ISO 8-bit code for information
interchange -- Structure and rules for implementation
},
ISO (1986).

\bibitem[ISO 6937/1]{iso6937/1} ISO,
{\em
Information processing -- Coded character sets for text
communication -- Part 1: General introduction
},
ISO (1983).

\bibitem[ISO 6937/2]{iso6937/2} ISO,
{\em
Information processing -- Coded character sets for text
communication -- Part 2: Latin alphabetic and non-alphabetic
graphic characters
},
ISO (1983).

\bibitem[ISO 8859/1]{iso8859/1} ISO,
{\em
Information processing -- 8-bit single-byte coded
graphic character sets -- Part 1: Latin alphabet No. 1
},
ISO (1987).

\bibitem[ISO 8859/2]{iso8859/2} ISO,
{\em
Information processing -- 8-bit single-byte coded
graphic character sets -- Part 2: Latin alphabet No. 2
},
ISO (1987).

\bibitem[ISO 8859/6]{iso8859/6} ISO,
{\em
Information processing -- 8-bit single-byte coded
graphic character sets -- Part 6: Latin/Arabic alphabet
},
ISO (1987).

\bibitem[ISO 8859/7]{iso8859/7} ISO,
{\em
Information processing -- 8-bit single-byte coded
graphic character sets -- Part 7: Latin/Greek alphabet
},
ISO (1987).

\bibitem[Kerns87]{kerns87} R. Kerns,
{\em
Extended Characters in Common LISP
},
X3J13 Character Subcommittee document, Symbolics Inc (1987).

\bibitem[Kurokawa88]{kurokawa88} T. Kurokawa, et al.,
{\em
Technical Issues on International Character Set Handling in Lisp
},
ISO/IEC SC22 WG16 document N33, (1988).

\bibitem[Linden87]{linden87} T. Linden,
{\em
Common LISP - Proposed Extensions for International Character Set
Handling
},
Version 01.11.87, IBM Corporation (1987).

\bibitem[Steele84]{steele84} G. Steele Jr.,
{\em
Common LISP: the Language
},
Digital Press (1984).

\bibitem[Xerox87]{xerox87} Xerox,
{\em
Character Code Standard, Xerox System Integration Standard
},
Xerox Corp. (1987).

\end{thebibliography}

\end{document}             % End of document.

∂23-Mar-89  0702	X3J13-mailer 	Re: 20 March cs proposal  
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89  07:02:51 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA01052; Thu, 23 Mar 89 08:02:48 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA12413; Thu, 23 Mar 89 08:02:45 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903231502.AA12413@defun.utah.edu>
Date: Thu, 23 Mar 89 08:02:44 MST
Subject: Re: 20 March cs proposal
To: Thom Linden <baggins@IBM.com>
Cc: Common Lisp mailing <x3j13@sail.stanford.edu>
In-Reply-To: Thom Linden <baggins@IBM.com>, Wed, 22 Mar 89 15:01:01 PST

> Sandra, if possible please put a DVI file out on cs.utah.edu again)

Done.  It's in the same place as before, ~ftp/pub/cl-cs-proposal.dvi.

-Sandra
-------

∂23-Mar-89  0903	X3J13-mailer 	Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 89  09:03:25 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 563608; Thu 23-Mar-89 12:03:12 EST
Date: Thu, 23 Mar 89 12:03 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)
To: x3j13@SAIL.STANFORD.EDU
In-Reply-To: <8903220438.AA22664@challenger>
Message-ID: <19890323170307.4.MOON@EUPHRATES.SCRC.Symbolics.COM>

It's not very important to me whether we call it a clarification
or a change.  What's more important is that we agree on a definition
of simple-array and that we get this issue behind us so we can move
on and finish this standard, so we can all go home.

The fundamental question, I think, is whether simple-array is a
conceptual type or a representation type.  I had assumed based on the
discussions that lead to the writing of CLtL, and on the lack of any
contradiction, that everyone agreed that it is a representation type and
all we had to do was state the details more clearly.  Apparently I was
mistaken.

Let me explain what I mean by those terms.  A conceptual type is one
that the programmer of a portable program thinks of as conceptually
distinct data.  For example, RATIO is a conceptual type.  No one thinks
a RATIO is another kind of CONS, and probably no one thinks a RATIO
is another kind of FLOAT.  All implementations agree on which objects
are of type RATIO and which are not.

A representation type is one that is not a conceptually distinct form of
data.  We have such types in the language in order to expose enough of
the implementation-dependent representation to permit user programs to
be specialized for one representation, so we can compile better code.
Representation types are a compromise between portability and
efficiency, and as such their definition is generally
implementation-dependent.  We define just enough about a representation
type so a programmer can figure out whether to use it, but we do not
constrain all implementations to use the same representation.  A
representation type is always a subtype of a conceptual type and
includes some, but not necessarily all, members of that conceptual type
that are implemented in some particularly efficient way.  A good example
of a representation type is FIXNUM.  Not all implementations agree on
which objects are of type FIXNUM.  However, we have defined FIXNUM
closely enough (it includes a certain range of the integers, as well as
possibly some other integers) to allow a programmer to decide whether a
given variable in a given program can or cannot be declared FIXNUM.  We
specify some integers that are guaranteed to be FIXNUM, but we do not
specify any integers that are guaranteed never to be FIXNUM in any
implementation.

Back to SIMPLE-ARRAY.  If SIMPLE-ARRAY is a conceptual type, then an
array is a SIMPLE-ARRAY if-and-only-if it meets certain criteria, and
all implementations must agree on exactly which objects are of type
SIMPLE-ARRAY.  Programmers would think of SIMPLE-ARRAYs as distinctly
different from ordinary arrays, and when programming would frequently
ask themselves "should I use a SIMPLE-ARRAY here or a regular ARRAY"
even when not thinking at all about efficiency or optimization.  They
would write their program differently depending on whether they used
a SIMPLE-ARRAY or a regular ARRAY, just as they would write their
program differently depending on whether they used a LIST or a VECTOR.

On the other hand, if SIMPLE-ARRAY is a representation type, then an
array is a SIMPLE-ARRAY if-and-only-if it is implemented with a
simpler, more efficient representation than regular arrays.  An array is
a SIMPLE-ARRAY if, but not only-if, it meets certain criteria.  In other
words we define a common intersection of the SIMPLE-ARRAY types of
all implementations, but we allow implementations to expand their
SIMPLE-ARRAY types to include other arrays, as appropriate to their
machine, just like FIXNUM, BASE-CHARACTER, and (ARRAY (UNSIGNED-BYTE 4)).
Programmers would only ask themselves "should this be a SIMPLE-ARRAY"
when thinking about efficiency and optimization.

I believe SIMPLE-ARRAY is a representation type because, as a
programmer, I don't think of it as conceptually different from an
ordinary array, and because, as a historian, I know that SIMPLE-ARRAY
was added to Common Lisp in 1982, and attained its current form in 1983,
in order to address the concern of many implementors that using the
fully general representation for all arrays would be too slow, as a
result of the large number of array features in Common Lisp.  The idea
was to permit use of a simpler, streamlined representation for some
arrays, and to make that representation available in TYPE declarations
so the compiler could optimize AREF on it.

To proceed, I think we should first reach a concensus on whether
SIMPLE-ARRAY is a conceptual or a representation type.  Once we have
done that, we will have a framework within which to decide the specific
details of its behavior.

∂23-Mar-89  1504	X3J13-mailer 	**DRAFT** Issue: PATHNAME-CANONICAL-TYPE (Version 1)    
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 89  12:07:40 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 563815; 23 Mar 89 15:06:56 EST
Date: Thu, 23 Mar 89 15:06 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** Issue: PATHNAME-CANONICAL-TYPE (Version 1)
To: X3J13@SAIL.Stanford.EDU
Message-ID: <890323150638.0.KMP@BOBOLINK.SCRC.Symbolics.COM>

	>>> PLEASE DO -NOT- REPLY TO THIS ISSUE <<<

Bring your comments to the meeting.

See summary of CL-Cleanup discussion at end of message.
 -kmp

-----
Issue:          PATHNAME-CANONICAL-TYPE
References:     MAKE-PATHNAME (p416)
Category:       ADDITION
Edit history:   07-Jul-88, Version 1 by Pitman
Status:	        For Internal Discussion
Related-Issues: PATHNAME-COMPONENT-CASE

Problem Description:

  The pathame-type of ``Lisp'' and ``Compiled Lisp'' files vary widely from
  implementation to implementation.

  "LSP" is common on Vax VMS. "lisp" is generally used for the Symbolics
  file system. "l" and "lisp" are common on Unix. Some Lisp implementations
  use customized extensions such as "cl" or even "jcl" (eg, for "Joe's CL").

  It would be useful to probe the existence of either a source or a binary
  file, but that cannot currently be done portably. Furthermore, it would be
  useful to create certain standard kinds of files in a system-independent
  fashion.

  A common desire, for example, is to do
    (DEFUN FILE-NEEDS-TO-BE-COMPILED (FILE)
      (LET ((SOURCE (PROBE-FILE
		      (MERGE-PATHNAMES FILE (MAKE-PATHNAME :TYPE ???))))
	    (BINARY (PROBE-FILE
		      (MERGE-PATHNAMES FILE (MAKE-PATHNAME :TYPE ???)))))
        ... (FILE-WRITE-DATE SOURCE) ... (FILE-WRITE-DATE BINARY) ...))
  The problem is that there's nothing portable to put in the ??? positions.

  Indeed, depending on the host (ie, file system) of the pathname, the
  type might need to differ even in the same Lisp implementation. For example,
  Symbolics Genera stores its source files in names like "foo.l" on Unix,
  "FOO.LSP" on VMS, etc.

Proposal (PATHNAME-CANONICAL-TYPE:NEW-CONCEPT):

  In addition to the normal strings and keywords currently allowed as fillers
  of the TYPE field of a pathname, allow other keywords which designate
  ``canonical types''. 

  A canonical type is translated to a real type by MAKE-PATHNAME so that the
  (PATHNAME-TYPE (MAKE-PATHNAME :TYPE canonical-type)) is a string.

  Introduce a new function PATHNAME-CANONICAL-TYPE which returns the canonical
  type of an argument pathname, or the type if there is no canonical type.
  For example,
    (PATHNAME-CANONICAL-TYPE (MAKE-PATHNAME :TYPE :LISP)) => :LISP
  [This information may be explicitly represented as an additional slot, or
  computed on demand using a lookup table, as the implementor prefers.]

  Define the following standard types:
	:LISP		``Lisp'' (source) file
	:BIN		``Compiled Lisp'' (object) file
  Permit implementations to extend the set of canonical type names.

Test Case:

  (PATHNAME-TYPE (MAKE-PATHNAME :TYPE :LISP))
   => "LSP" 	    ;Typically, on VMS
   => "l" or "lisp" ;Typically, on Unix
   => "L" or "LISP" ;Typically, on Unix 
		    ; (assuming PATHNAME-COMPONENT-CASE:CANONICALIZE adopted)
   ..etc.

  (PATHNAME-TYPE (MAKE-PATHNAME :TYPE :BIN))
   => "FAS" 	    ;eg, VAXLISP
   => "BIN"	    ;eg, Symbolics file system
   ...etc.

  (PATHNAME-CANONICAL-TYPE (MAKE-PATHNAME :TYPE :LISP)) => :LISP

  (PATHNAME-CANONICAL-TYPE (MAKE-PATHNAME :TYPE "LSP"))
   => :LISP	    ;eg, VAXLISP
   => "LSP"	    ;eg, Unix

Rationale:

  This is a useful subset of the functionality already available in
  at least one implementation.

Current Practice:

  Symbolics Genera implements this proposal.

Cost to Implementors:

  The cost of implementing these proposed features is very slightly.

  MAKE-PATHNAME would have to change to coerce its :TYPE argument in implementations
  where it does not do so already. PATHNAME-CANONICAL-TYPE can be implemented as a
  fairly straightforward lookup.

Cost to Users:

  None. This change is upward compatible.

Cost of Non-Adoption:

  It would continue to be hard to portably name files when their types
  differed from file system to file system.

Benefits:

  The cost of non-adoption would be avoided.

Aesthetics:

  Some programs would be able to abstract away from the particulars of the host
  file system entirely. Some people believe this would be a definite improvement
  in aesthetics.

Discussion:

  Note that different Lisp implementations which share the same file system,
  need not and perhaps should not agree on the same type string for the
  canonical type :BIN. That is, if I store source files on VAX VMS and compile
  them both for use under Symbolics Genera and VAXLISP, then it is both
  appropriate and useful that VAXLISP :BIN files be named "something.FAS"
  and Genera :BIN files be named "something.BIN" since then they wouldn't
  clobber each other.

  Pitman supports PATHNAME-CANONICAL-TYPE:NEW-CONCEPT.

-------

Summary of discussion on CL-Cleanup:

 GZ suggested :COMPILED-LISP was suggested as a better name than :BIN.
 Masinter thought :SOURCE-LISP might be better than :LISP. Either of these
 would be gratuitously incompatible with Symbolics Genera, which already
 implements canonical types, but otherwise not technically unreasonable
 and probably something we should discuss.

 Sandra Loosemore offered the following revealing piece of code from her
 work and asked why we couldn't just do this.

  (defvar *binary-file-type*
      #+Symbolics                         (make-pathname :type "bin")
      #+(and dec common vax (not ultrix)) (make-pathname :type "FAS")
      #+(and dec common vax ultrix)       (make-pathname :type "fas")
      #+pcls                              (make-pathname :type "b")
      #+KCL                               (make-pathname :type "o")
      #+Xerox                             (make-pathname :type "dfasl")
      #+(and Lucid MC68000)               (make-pathname :type "lbin")
      #+(and Lucid VAX VMS)               (make-pathname :type "vbin")
      #+excl                              (make-pathname :type "fasl")
      #+system::cmu                       (make-pathname :type "sfasl")
      #+PRIME                             (make-pathname :type "pbin")
      #+HP                                (make-pathname :type "b")
      #+TI                                (make-pathname :type "xfasl")
      "The default file type for compiled files.")

 The reason is that some implementations (e.g., Symbolics) deal with more
 than one file system type -- and properly the information varies with the
 file system type, not with the implementations.  [Since most implementations
 have only one associated file system type, this may not be obvious, but it's
 quite obvious on a Symbolics machine that you vary the extension name based
 on the host file system requirements.]

 Moon suggested a compromise where *compile-file-output-type* (his name
 for Sandra's *binary-file-type*) existed but could be either a canonical
 type or a physical type.

 Masinter worries about the PATHNAME-CANONICAL-TYPE part of the proposal
 being forced to be heuristic in some cases. [Will any alternative be any
 less heuristic? -kmp]

 Moon wanted the following example to be guaranteed to work:
   (PATHNAME-CANONICAL-TYPE (PATHNAME "foo.lisp")) => :LISP
 where of course the string is implementation-dependent.  That is,
 PATHNAME-CANONICAL-TYPE must produce a canonical type even when the
 pathname was not constructed from a canonical type, but instead came
 from user typein, the TRUENAME function, the DIRECTORY function,
 or some similar source, when the pathname's type is one that a
 canonical type maps into.

 Moon also thought it would be nice to have a facility for users 
 (in addition to implementations) to extend the set of canonical type
 names, since users may well have their own types of files.  However,
 he admitted that the difficulty is that in any system that supports
 multiple file systems, it has to be complex enough to allow
 specification of separate mappings for each file system, which in
 turn requires a way to name file system types.  [At this point, we
 probably don't have time left in our schedule to produce such a
 facility. -kmp]

∂23-Mar-89  1503	X3J13-mailer 	**DRAFT** Issue: PATHNAME-EXTENSIONS (Version 1)   
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 89  11:47:13 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 563798; Thu 23-Mar-89 14:47:01 EST
Date: Thu, 23 Mar 89 14:46 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** Issue: PATHNAME-EXTENSIONS (Version 1)
To: X3J13@SAIL.Stanford.EDU
Message-ID: <890323144641.9.KMP@BOBOLINK.SCRC.Symbolics.COM>

	>>> PLEASE DO -NOT- REPLY TO THIS MESSAGE <<<

It's probably so late that no one will read what you have to say
anyway. Ponder it and bring your comments to the meeting.

Summary of debate on CL-Cleanup follows at end.
 -kmp

-----
Issue:        PATHNAME-EXTENSIONS
Forum:	      Cleanup
References:   Pathnames (pp410-413)
Category:     ADDITION
Edit history: 28-Dec-88, Version 1 by Pitman
Status:	      For Internal Discussion

Problem Description:

  CLtL is quite strict about what may and may not be in any kind of
  pathname, leaving implementors up against a brick wall when an
  idiosyncratic extension is necessary to uniquely and usefully 
  represent all files in a particular file system which may not have
  been completely anticipated by the Common Lisp designers.

Proposal (PATHNAME-EXTENSIONS:NEW-PREDICATE):

  Introduce a function COMMON-PATHNAME-P, described as follows:

	COMMON-PATHNAME-P pathname			[Function]

	Returns true if its argument satisfies the Common Lisp
	pathname model, and false otherwise. If the argument is
	not a pathname, an error of type TYPE-ERROR is signalled.

  Clarify that COMMON-PATHNAME-P considers a pathname's host field
  to fit the Common Lisp pathname model if the filler of the host
  field is a string (naming a host), and not otherwise.

  Clarify that COMMON-PATHNAME-P considers a pathname's device to fit
  the Common Lisp pathname model if it is a string naming a device,
  or NIL, or :WILD[, or, if issue PATHNAME-COMPONENT-UNSPECIFIC 
  passes, is :UNSPECIFIC], and not otherwise.

  Clarify that COMMON-PATHNAME-P considers a pathname's directory
  field to fit the Common Lisp pathname model if the filler of the
  directory field is NIL, or :WILD, or a string[, or, if issue
  PATHNAME-SUBDIRECTORY-LIST passes, is a list described as valid
  by that proposal][, or, if issue PATHNAME-COMPONENT-UNSPECIFIC 
  passes, is :UNSPECIFIC], and not otherwise.

  Clarify that COMMON-PATHNAME-P considers a pathname's name to 
  fit the Common Lisp pathname model if it is a string, or NIL,
  or :WILD, and not otherwise.
  
  Clarify that COMMON-PATHNAME-P considers a pathname's type to
  fit the Common Lisp pathname model if it is a string, or :WILD,
  or NIL[, or, if issue PATHNAME-COMPONENT-UNSPECIFIC passes, is
  :UNSPECIFIC], and not otherwise.

  Clarify that COMMON-PATHNAME-P considers a pathname's version to
  fit the Common Lisp pathname model if it is a positive integer,
  :WILD, or NIL, or :NEWEST[, or, if issue PATHNAME-COMPONENT-UNSPECIFIC
  passes, is :UNSPECIFIC], and not otherwise.

  Clarify that COMMON-PATHNAME-P considers a pathname to be outside
  the Common Lisp model if it contains special syntax or purpose 
  which is not readily apparent to Common Lisp programs. For example,
  if a character like "*" or "~" has special meaning to the file 
  system, then strings like "F*X" or "~FOO" which exploit that syntax
  are not considered to "fit the model". [Note that if issue
  PATHNAME-WILD passes, WILD-PATHNAME-P might still be true of
  some pathnames that were not COMMON-PATHNAME-P.]

Test Case:

  ;; On Unix...

  (common-pathname-p (make-pathname :name "f*x"))
  => nil

  ;; On Tops-20...

  (common-pathname-p (make-pathname :name "FOO" :version -1))

  ;; On VMS...

  (common-pathname-p (parse-namestring "x::y::z::w::[joe]a.b"))
  => nil

  ;; Normally

  (common-pathname-p (make-pathname :name "FOO" :version :wild))
  => t

  (common-pathname-p (make-pathname :name "FOO" :version 17))
  => t

Rationale:

  The purpose of COMMON-PATHNAME-P is not to detect pathnames which
  are not valid. Indeed, no Common Lisp function requires that its 
  argument satisfy this test; it is assumed that functions such as
  OPEN and MERGE-PATHNAMES will recognize and deal appropriately with
  whatever special pathname syntax is appropriate to the host operating
  system. Rather, the purpose of COMMON-PATHNAME-P is to help Common 
  Lisp programs which try to pick apart a pathname and perform some
  sort of simulated merging on the basis of the simple pathname model
  put forth by Common Lisp, so that such programs can detect situations
  which are beyond their capabilities.

Current Practice:

  Probably nobody implements this.

Cost to Implementors:

  Small. The program is fairly straightforward. It could almost be
  written as a portable library if it weren't for detecting special
  characters that have some special syntax.

Cost to Users:

  None. This change is upward compatible.

Cost of Non-Adoption:

  Some idiosyncratic system syntax would be hard to detect.

  Making extensions to the pathname system in a way that Common Lisp
  users would not be forced to trip over would be more difficult.

Benefits:

  Some ad-hoc user code which tries to do the same thing could be
  eliminated. Portable programs which must prompt for native pathname
  syntax, and deal with the result of having parsed it could be more
  robust.

  Making idiosyncratic extensions to the pathname system would be much
  less prone to cause problem for portable programs which used this 
  facility.

  The presence of this operator could someday ease the transition
  into a future, incompatible pathname system.

Aesthetics:

  Probably improves aesthetics slightly by giving people who want to
  reject extended pathnames a more reliable way of weeding them out.

Discussion:

  The COMMON data type was probably intended to have this same purpose.
  Unfortunately, since no one ever really said specifically enough what
  was in COMMON or not, and why, it never really caught on. Hopefully
  this proposal is definite enough on such issues to not be useless.

  Pitman thinks this is probably a good idea.

------- Summary of debate -------

Discussion on CL-Cleanup centered around two issues:

 - Is this really needed?  What could it be used for?

   I suggested following program as an illustration:

   (DEFUN TRANSLATE-LOGICAL-PATHNAME (LPATHNAME)
     (MULTIPLE-VALUE-BIND (LHOST LDEVICE LDIR LNAME LTYPE LVERSION)
	 (PARSE-LOGICAL-PATHNAME LPATHNAME)
       (MULTIPLE-VALUE-BIND (PHOST PDEVICE PDIR PNAME PTYPE PVERSION)
	   (TRANSLATE-PATHNAME-COMPONENTS LHOST LDEVICE LDIR LNAME LTYPE LVERSION)
	 (LET ((PHYSICAL-PATHNAME (MAKE-PATHNAME :HOST PHOST ...)))
	   (UNLESS (COMMON-PATHNAME-P PHYSICAL-PATHNAME)
	     (CERROR "Use ~*~A anyway."
		     "The result of translating pathname ~A to a physical pathname~
		    ~%resulted in a valid physical pathname, ~A,~
		    ~%but that pathname has special meaning to host ~A which may~
		    ~%not have been what was intended."
		     LPATHNAME PHYSICAL-PATHNAME PHOST))))))

   Also, recently there has been concern (e.g., in issue
   PATHNAME-SUBDIRECTORY-LIST) about requirements for conformance
   precluding interesting extensions that particular implementations
   might want to experiment with.  This would provide a way for portable
   programs to guard against such `creative' extensions.

 - Isn't this something users could write?

   The answer is no.  What is a non-portable pathname cannot be portably
   detected. e.g., the fact that "*" or "~" or "{" or whatever is magic
   in some filename syntax and not in another is (almost by definition) not 
   something that is portably detectable.  Portable programs can just decide
   to limit themselves to the least common denominator (e.g., refusing to let
   you type in any pathname to a prompt for pathname if it has an `scary
   looking' character in it), but this provides a way of being both a little
   more robust and a little more tolerant.

For those who are curious, I'm not adamant about this proposal. I just
want it to be available as an option in case it eases the discussion on
other issues.
 -kmp

∂23-Mar-89  1503	X3J13-mailer 	issue CLOS-MACRO-COMPILATION, version 3  
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89  11:35:38 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA10107; Thu, 23 Mar 89 12:35:34 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA12651; Thu, 23 Mar 89 12:35:31 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903231935.AA12651@defun.utah.edu>
Date: Thu, 23 Mar 89 12:35:30 MST
Subject: issue CLOS-MACRO-COMPILATION, version 3
To: x3j13@sail.stanford.edu

This is a revised version of the writeup that was sent out last week.
The major change is to the language about error situations under
DEFMETHOD.

Forum:		Compiler
Issue:		CLOS-MACRO-COMPILATION
References:	CLOS chapters 1 & 2 (88-002R)
		CLOS chapter 3 (89-003)
		Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
		Issue DEFINING-MACROS-NON-TOP-LEVEL
Category:	CLARIFICATION
Edit History:   V1, 10 Mar 1989, Sandra Loosemore
		V2, 13 Mar 1989, Sandra Loosemore
		V3, 21 Mar 1989, Sandra Loosemore (fix error language)
Status:		Ready for release


Problem Description:

Do the CLOS defining macros (DEFCLASS, DEFMETHOD, DEFGENERIC, and
DEFINE-METHOD-COMBINATION) have compile-time side-effects similar
to those for DEFSTRUCT or DEFMACRO?

A part of the problem is that we do not currently have a full
understanding of all the issues involved.  In particular, work on
defining the CLOS meta-object protocol is still in progress.  The goal
of this proposal is to say enough about the behavior of these macros
in the standard so that users can use them portably in compiled code,
but to leave as much of the behavior as possible unspecified to avoid
placing undue restrictions on the meta-object protocol.

There are two proposals, MINIMAL and NOT-SO-MINIMAL.


Proposal CLOS-MACRO-COMPILATION:MINIMAL:

 State that top-level calls to the CLOS defining macros have the
 following compile-time side-effects.  Any other compile-time behavior
 is explicitly left unspecified.

  DEFCLASS:
  
  * The class name becomes a type specifier which may appear in 
    subsequent type declarations.
  
  * The class name can be used to name a superclass in a subsequent
    DEFCLASS.
  
  * The class name can be used as a specializer in a subsequent 
    DEFMETHOD.
  
  DEFGENERIC:
  
  * The generic function can be referenced in a subsequent DEFMETHOD.  

  * The generic function is not callable at compile-time.
  
  DEFMETHOD:
  
  * The method is not callable at compile-time.  If there is a generic
    function with the same name at compile-time, compiling a DEFMETHOD
    will not add the method to that generic function.  

    The error-signalling behavior described in the specification of
    DEFMETHOD in CLOS chapter 2 (if the function isn't a generic function
    or if the lambda-list is not congruent) happens only at run time,
    not at compile time.
    
  DEFINE-METHOD-COMBINATION:
  
  * The method combination can be used in a subsequent DEFGENERIC.  If it
    is referenced, the body of a long form of method combination must be 
    evaluable at compile-time.

 Rationale:

  The compile-time behavior of DEFCLASS is similar to DEFSTRUCT or
  DEFTYPE.  

  DEFGENERIC and DEFMETHOD are similar to DEFUN, which doesn't add the
  function definition to the compile-time environment.  Since generic
  functions may be freely redefined between compile and run time (just
  like any other function), a method may end up "belonging" to a
  different generic function at load time than at compile time.  This
  is why it is inappropriate to signal errors about congruency problems
  (etc) until the method is actually added to the generic function at
  run time.

  Some implementations compose effective methods at compile time, which
  requires evaluating the body of the DEFINE-METHOD-COMBINATION at
  compile time.


Proposal CLOS-MACRO-COMPILATION:NOT-SO-MINIMAL:

 This is the same as proposal MINIMAL, except under DEFCLASS add:

  * The class may be instantiated at compile-time.  Provided the 
    appropriate methods are also defined at compile-time, this implies:
    - The class can be used as the :METACLASS option of a later DEFCLASS.
    - It can be used as the :GENERIC-FUNCTION-CLASS or :METHOD-CLASS option
      of a DEFGENERIC, GENERIC-FUNCTION, GENERIC-FLET, or GENERIC-LABELS.

 Rationale:

  Being able to instantiate a class at compile-time is somewhat more 
  convenient for users.


Current Practice:

  The items listed under DEFCLASS in proposal MINIMAL are fairly standard
  programming style.

  Flavors does not support compile-time instantiation of classes.  It
  does not make method combinations available at compile-time either, but
  Moon considers that to be a bad design choice.

Cost to implementors:

  Unknown.

Cost to users:

  Unknown, but probably fairly small.

  Note that for proposal NOT-SO-MINIMAL, users still have to ensure that
  any methods on the class which may be invoked at compile-time are 
  fully defined.  This includes the INITIALIZE-INSTANCE and 
  SHARED-INITIALIZE methods that are invoked by MAKE-INSTANCE.

  Wrapping an (EVAL-WHEN (EVAL COMPILE LOAD) ...) around the appropriate
  definitions will make sure they are fully defined at compile-time.
  Alternatively, the definitions could be placed in a separate file,
  which is loaded before compiling the file that depends on those
  definitions.

Benefits:

  Programmers can rely on programs that use the CLOS defining macros 
  being able to compile correctly in all implementations, without having
  to wrap explicit EVAL-WHENs around every macro call.

Discussion:

  This writeup is based on discussions between Moon, Gray, and
  Loosemore, who are mostly in agreement on the things presented in
  proposal MINIMAL.  We have purposely avoided saying anything about
  whether meta-objects representing the classes, methods, etc. get
  created at compile-time, or whether such meta-objects are fully or
  partially defined.  The basic questions addressed by this issue are
  what kinds of things can be defined and then used during compilation
  of the same file that defines them, and what restrictions might apply.

  These proposals are not completely compatible with the meta-object 
  protocol document (89-003).  Gregor Kiczales says:
    No one believes that what is written in draft 10 of the MOP is valid.

  Sandra Loosemore says:
    Although I admit I don't understand all of the issues involved with
    the meta-object protocol, I prefer proposal MINIMAL over 
    NOT-SO-MINIMAL.  I don't think leaving the issue of whether or not
    classes can be instantiated at compile-time unspecified places an
    undue burden on users, and it does leave more freedom for the
    meta-object protocol to decide what the right behavior really is.

  Dick Gabriel notes:
    The question I have about the process going on with respect to the
    CLOS-MACRO-COMPILATION issue is whether the fine-grained behavior of
    CLOS under various compilation/evaluation situations is being
    over-specified. 

    At this stage of the game I worry that we might go a little too far in
    one direction in specification when we are actually engaged in design
    work. This isn't intended to be a criticism of any committees, but I
    would feel a lot more comfortable with a conservative specification
    that defined well-formed programs being loaded or compiled in fresh
    Common Lisps with a pretty simple eval-when model that is easier to
    specify and which makes it easy for all but the hairiest
    compilation-environment-frobbing programs to be written.

-------

∂23-Mar-89  1504	X3J13-mailer 	Issue: PATHNAME-WILD (Version 2)    
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 89  12:11:23 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 563820; Thu 23-Mar-89 15:11:10 EST
Date: Thu, 23 Mar 89 15:10 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: PATHNAME-WILD (Version 2)
To: X3J13@SAIL.Stanford.EDU
Message-ID: <890323151049.1.KMP@BOBOLINK.SCRC.Symbolics.COM>

	>>> PLEASE DO -NOT- REPLY TO THIS ISSUE <<<

Please just ponder it and bring your comments to the meeting.

My notes say that at the Fairfax meeting, we (the Cleanup committee)
thought this was ready for vote.  This was held up in hopes of a unified
pathname proposal which did not materialize, and then got lost in the
shuffle.
 -kmp

-----
Issue:        PATHNAME-WILD
References:   Pathnames (pp410-413)
Category:     ADDITION
Edit history: 21-Jul-88, Version 1 by Pitman
	      06-Oct-88, Version 2 by Pitman
Status:	      For Internal Discussion

Problem Description:

  Some file systems provide more complex conventions for wildcards than
  simple component-wise wildcards. For example,

  "F*O" might mean:
    - a normal three character name
    - a three-character name, with the middle char wild
    - at least a two-character name, with the middle 0 or more chars wild
    - a wild match spanning multiple directories

  ">foo>*>bar" might imply:
    - the middle directory is named "*"
    - the middle directory is :WILD
    - there may be zero or more :WILD middle directories
    - the middle directory name matches any one-letter name

  ">foo>**>bar" might mean
    - the middle directory is named "**"
    - the middle directory is :WILD
    - there may be zero or more :WILD middle directories
    - the middle directory name matches any two-letter name

  The CL pathname model does not provide a way to represent such wildcards,
  which means, for example, that (MAKE-PATHNAME :NAME "F*O") cannot be
  recognized by portable code as containing a wildcard.

  CL code needs to at least be able to detect and possibly to manipulate
  such wildcard pathnames.

Proposal (PATHNAME-WILD:NEW-FUNCTION):

  Introduce the following function:

   WILD-PATHNAME-P pathname &optional field-key			[Function]
 
   Tests a pathname for the presence of wildcard components.
   If the first argument is not a pathname an error is signalled.
 
   If no field-key is provided, or the field-key is NIL, this function
   returns true if the argument pathname has any wildcard components.
   Otherwise, it returns false.
 
   If a non-null field-key is provided, it must be one of :HOST, :DEVICE,
   :DIRECTORY, :NAME, :TYPE, or :VERSION. In this case, it returns true
   if the argument pathname is wild in the indicated component. Otherwise,
   it returns false.

Test Case:

  #1: (WILD-PATHNAME-P (MAKE-PATHNAME :NAME :WILD)) => T

  #2: (WILD-PATHNAME-P (MAKE-PATHNAME :NAME :WILD) :NAME) => T

  #3: (WILD-PATHNAME-P (MAKE-PATHNAME :NAME :WILD) :TYPE) => NIL

  #4: (WILD-PATHNAME-P (PATHNAME "S:>foo>**>")) => T   ;Lispm

  #4: (WILD-PATHNAME-P (PATHNAME :NAME "F*O")) => T ;Most places

Rationale:

  If the programmer can at least detect wild pathnames reliably,
  he can know to do something useful (give up, merge out the bothersome
  components, call DIRECTORY for a list of matching pathnames, etc.)

Current Practice:

  Presumably no implemenation supports the proposal exactly as stated.

  Symbolics Genera provides the ability to do
    (SEND pathname :WILD-P)
  which returns a value such as NIL, :NAME, :TYPE, etc. In the case
  that more than one field is wild, however, some information is lost.

Cost to Implementors:

  Many implementations probably have a substrate which is capable of this
  or something similar already. In such cases, it's a relatively small
  matter to add the proposed interface.

  Even in cases where an implementation doesn't have ready code, it's clearly
  better for the implementor to write that code once and for all than to ask
  each user of wildcarded code to write it (often more heuristically).

Cost to Users:

  None. This change is upward compatible.

Cost of Non-Adoption:

  Wild pathnames would continue to be mistaken for ordinary pathnames in
  situations which CL pathnames cannot represent.

Benefits:

  Portable user interfaces that prompt users for pathnames could more
  reliably detect wildcard pathnames and more easily guard against
  embarrassing behavior in such situations.

Aesthetics:

  This change would make some portable code less kludgey.

Discussion:

  Pitman supports PATHNAME-WILD:NEW-FUNCTION.

  It would have been possible for this function to have accepted
  a string as an argument (coercing it to a pathnames), but that
  would have entailed adding an optional host argument. We opted
  not to do this.

  There was some question about the name. The name PATHNAME-WILD-P
  suggests a ``slot'' of a pathname (like PATHNAME-HOST),
  while WILD-PATHNAME-P suggests a type (like INPUT-STREAM-P).
  The committee was split on what to call it. Since it is more
  like a type than a slot, the name WILD-PATHNAME-P was chosen.

∂23-Mar-89  1503	X3J13-mailer 	issue COMPILE-ENVIRONMENT-CONSISTENCY, version 5   
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89  11:40:15 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA10248; Thu, 23 Mar 89 12:40:04 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA12657; Thu, 23 Mar 89 12:39:59 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903231939.AA12657@defun.utah.edu>
Date: Thu, 23 Mar 89 12:39:58 MST
Subject: issue COMPILE-ENVIRONMENT-CONSISTENCY, version 5
To: x3j13@sail.stanford.edu

This version of the writeup has had a few changes made to the error
language in items 2 and 3.

Forum:		Compiler
Issue:		COMPILE-ENVIRONMENT-CONSISTENCY
References:	CLtL p. 68-69, 143, 321
		RAM's "Compiler Cleanup Proposal #3"
Category:	CLARIFICATION
Edit History:   V1, 2 Sep 1988, Sandra Loosemore (initial draft)
		V2, 9 Sep 1988, Sandra Loosemore (incorporate suggestions)
		V3, 26 Oct 1988, Sandra Loosemore (add suggestion from Benson)
		V4, 08 Mar 1989, Sandra Loosemore (wording changes)
		V5, 22 Mar 1989, Sandra Loosemore (fix error language)


Problem Description:

CLtL does not clearly specify what aspects of the compiletime
environment the compiler (or other preprocessor) may "wire in" to code
being compiled.  At what time (compiletime or runtime) are certain
kinds of definitions "captured"?  What happens if these definitions
are not consistent at both compile and run times?


Proposal COMPILE-ENVIRONMENT-CONSISTENCY:CLARIFY:

The process of compilation causes certain kinds of information present
in the compiletime environment to be captured and incorporated into
the resulting compiled code.  Other kinds of information may not be
captured until the compiled code is actually run.  

Specifically:

(1) The following information *must* be present in the compiletime
environment for the program to be compiled correctly.  This
information need not also be present in the runtime environment.

    (a) In conforming code, macros referenced in the code being compiled
        must have been previously defined in the compiletime environment.
	The compiler must treat any form that is a list beginning with
	a symbol that does not name a macro or special form as a function
	call.  (This implies that SETF methods must also be available at
	compiletime.)

    (b) In conforming code, proclamations for SPECIAL variables must
        be made in the compiletime environment before any bindings of
        those variables are processed by the compiler.  The compiler
        must treat any binding of an undeclared variable as a lexical
        binding.


(2) The compiler *may* incorporate the following kinds of information
into the code it produces, if the information is present in the
compiletime environment and is referenced within the code being
compiled.  Except where some other behavior is explicitly stated, when
the compiletime and runtime definitions are different, it is
unspecified which will prevail within the compiled code.  It is also
permissible for implementations to signal an error at runtime to
complain about the discrepancy.  In all cases, the absence of the
information at compiletime is not an error, but its presence may
enable the compiler to generate more efficient code.

    (a) The compiler may assume that functions that are defined and
	declared INLINE in the compiletime environment will retain the
        same definitions at runtime.

    (b) The compiler may assume that, within a named function, a
	recursive call to a function of the same name refers to the
	same function, unless that function has been declared NOTINLINE.

    (c) COMPILE-FILE may assume that, in the absence of NOTINLINE
	declarations, a call within the file being compiled to a named
	function which is defined in that file refers to that function.
	(This permits "block compilation" of files.)  The behavior of
	the program is unspecified if functions are redefined individually 
	at runtime.

    (d) The compiler may assume that the signature (or "contract") of
	all built-in Common Lisp functions will not change.  In addition,
	the compiler may treat all built-in Common Lisp functions as if
	they had been proclaimed INLINE.

    (e) The compiler may assume that the signature (or "contract") of
	functions with FTYPE information available will not change.  (See
	issue FUNCTION-TYPE-ARGUMENT-TYPE-SEMANTICS.)

    (f) The compiler may "wire in" the values of symbolic constants
	that have been defined with DEFCONSTANT in the compiletime
	environment.

    (g) The compiler can assume that type definitions made with DEFTYPE 
        or DEFSTRUCT in the compiletime environment will retain the same 
        definition in the runtime environment.  It may also assume that
        a class defined by DEFCLASS in the compiletime environment will
        be defined in the runtime environment in such a way as to have
        the same superclasses and metaclass.  This implies that
        subtype/supertype relationships of type specifiers will not 
        change between compiletime and runtime.  (Note that it is not 
        an error for an	unknown type to appear in a declaration at
        compiletime, although it is reasonable for the compiler to 
        emit a warning in such a case.)

    (h) The compiler may assume that if type declarations are present
	in the compiletime environment, the corresponding variables and 
	functions present in the runtime environment will actually be of
	those types; otherwise, the runtime behavior of the program is 
	undefined.


(3) The compiler *must not* make any additional assumptions about
consistency between the compiletime and runtime environments.  In 
particular:

    (a) The compiler may not assume that functions that are defined
	in the compiletime environment will retain the either the
	same definition or the same signature at runtime, except
	in situations (2a) through (2e) above.

    (b) The compiler may not signal an error if it sees a call to a
	function that is not defined at compiletime, since that function
	may be provided at runtime.

	

Rationale:

This proposal generally reflects current practice.


Current Practice:

There don't seem to be any compilers around that do not implement the
provisions of item (1).

For item (2), most compilers (including Lucid) optimize self-recursive
calls by default.  Most compilers also opencode data structure
accessors (such as CAR) at some level of optimization, and some code
much more complicated built-in functions inline as well.  VaxLisp, for
example, normally compiles MEMBER inline.  The Lucid compiler makes
use of type declarations to perform generic-to-specific
transformations on many arithmetic and sequence functions, which is
also a form of inlining.  KCL performs block compilation by default,
and Lucid does so under certain conditions.


Cost to implementors:

Unknown, but probably minor.


Cost to users:

Since most implementations appear to be largely in conformance with the
proposal, users should notice little difference.


Benefits:

The presence of a definite specification of what may happen when will
help users structure their programs so they will compile correctly in
all Common Lisp implementations.


Discussion:

Most of the discussion on this issue has been centered on the
terminology describing error situations for item (2).  In most cases
where there is an inconsistency between compile-time and run-time, the
results will be unpredictable but harmless.  The major exception is
violation of type declarations, which is a "crash-and-burn" error in
many implementations.

There has also been some concern raised that item (3) would prohibit
such things as a cross-compiler that produces standalone programs in
an environment that disallows redefinition of functions.  The intent
of this proposal is not to prohibit a compiler from having a magic
switch that imposes additional restrictions on the programs it
compiles, but such a compiler would not be a compiler for Common Lisp.

Several people have expressed reservations about items 2b and 2c, saying
that self-tail-recursion optimization and block compilation should not
be the default behavior of the compiler.  Gail Zacharias responds:

  This item [2c] has nothing to do with whether anybody does it by
  default.  The question is whether an end user can take a Common Lisp
  program whose internals he's not familiar with, block-compile it, and
  be guaranteed that it will continue to function correctly.  This item
  says that yes, a correct CL program must explicitly indicate what
  functions in the source it will redefine at runtime.  I don't think
  this places such a great burden on the programmer.  Without this
  provision, only somebody intimately familiar with a program could know
  whether it can be safely block-compiled, making block-compilation
  useless in the context of portable CL programs.
  
  This thing about "block compilation shouldn't be the default" seems to
  come up every time this item is discussed.  That's an environment
  question and is not addressed by the proposal.  The proposal simply
  says that block compilation should be legal.
-------

∂23-Mar-89  1503	X3J13-mailer 	Issue: REMF-DESTRUCTION-UNSPECIFIED, v.6 
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 23 Mar 89  12:25:28 PST
Received: from Cabernet.ms by ArpaGateway.ms ; 23 MAR 89 12:07:04 PST
Date: 23 Mar 89 12:06 PST
From: masinter.pa@Xerox.COM
to: x3J13@sail.stanford.edu
Subject: Issue: REMF-DESTRUCTION-UNSPECIFIED, v.6
Message-ID: <890323-120704-5187@Xerox>

This issue was tabled from the Jan. 89 meeting, and amended
by Barry Margolin as discussed there.

!
Issue:        REMF-DESTRUCTION-UNSPECIFIED
References:   (SETF (GET ...) ...), REMPROP, (SETF (GETF ...) ...),
	      REMF (pp165-167); NREVERSE (p248); DELETE, DELETE-IF,
	      DELETE-DUPLICATES, NSUBSTITUTE, NSUBSTITUTE-IF (pp254-256); 
	      NCONC, NRECONC (p269); NUNION, NINTERSECTION,
	      NSET-EXCLUSIVE-OR (pp276-279).
Category:     CLARIFICATION/CHANGE
Edit history: 11-Feb-87, Version 1 by Dave Andre (DLA@Symbolics.COM)
	      29-Oct-87, Version 2 by Pitman (flesh out proposals)
	      28-Nov-88, Version 3 by Pitman (revised presentation)
	      29-Nov-88, Version 4 by Pitman (slight editing per DLA)
	      15-Mar-89, Version 5 by Margolin (amendments discussed in
			 Hawaii, removed -NOT functions)
	      17-Mar-89, Version 6 by Margolin (make NSUBSTITUTE* less vague)

Problem Description:

 Currently, the exact nature of the side-effect performed by list
 modification routines is not specified.

 Either the specific modifications allowed should be specified so that
 programmers can rely on them and implementors can avoid accidentally
 causing problems by introducing well-meaning optimizations, or else
 the documentation should explicitly state that the effects are
 unspecified so that programmers will not depend on them and 
 implementors will feel comfortable about doing interesting optimizations.

Proposal (REMF-DESTRUCTION-UNSPECIFIED:EXPLICITLY-VAGUE-EXCEPT-NCONC-AND-NSUBSTITUTE):

 [This proposal name is getting way out of hand!]

 Clarify that the way in which the destructive behavior of the
 operators below is achieved is explicitly vague in a number of ways,
 in order to provide individual implementations the necessary
 flexibility to do useful optimizations.

 (SETF (GETF place indicator) value)
  is permitted to either SETF place or to SETF any part, CAR or
  CDR, of the top-level list structure held by that place.

 (REMF place indicator)
  is permitted to either SETF place or to SETF any part, CAR or
  CDR, of the top-level list structure held by that place.

 (SETF (GET symbol indicator) value)
  is constrained to behave exactly the same as
  (SETF (GETF (SYMBOL-PLIST symbol) indicator) value).

 (REMPROP symbol indicator)
  is constrained to behave exactly the same as
  (REMF (SYMBOL-PLIST symbol) indicator).

 (NREVERSE sequence)
  when sequence is a list, is permitted to SETF any part, CAR or
   CDR, of the top-level list structure in that sequence.
  when sequence is an array is permitted to re-order the elements
   of the given sequence in order to produce the resulting array.

 (DELETE object sequence ...)
  when sequence is a list, is permitted to SETF any part, CAR or
   CDR, of the top-level list structure held in that sequence.
  when sequence is an array is permitted to change the dimensions
   of the array and to slide its elements into new positions without
   permuting them to produce the resulting array.
  
 (DELETE-IF test sequence ...)
  is constrained to behave exactly like
  (DELETE NIL sequence
	  :TEST #'(LAMBDA (IGNORE ITEM) (FUNCALL test ITEM))
	  ...).

 (DELETE-DUPLICATES sequence ...)
  when sequence is a list, is permitted to SETF any part, CAR or
   CDR, of the top-level list structure held in that sequence.
  when sequence is an array is permitted to change the dimensions
   of the array and to slide its elements into new positions without
   permuting them to produce the resulting array.

 (NRECONC list tail)
  is constrained to have side-effect behavior equivalent to:
  (NCONC (NREVERSE list) tail).

 (NUNION list1 list2 ...)
 (NINTERSECTION list1 list2 ...)
 (NSET-EXCLUSIVE-OR list1 list2 ...)
  is permitted to SETF any part, CAR or CDR, of the top-level of
  any of the given lists.

  Note, however, that since this side-effect is not required,
  these functions should still not be used in for-effect-only
  positions in portable code.

 (NCONC . lists)
  is defined using the following recursive relationship:

    (NCONC) => NIL
    (NCONC NIL . args) == (NCONC . args)
    (NCONC arg) => arg
    (NCONC arg1 arg2) has the side effect of (RPLACD (LAST arg1) arg2),
		      and returns arg1 
    (NCONC arg1 arg2 . args) == (NCONC (NCONC arg1 arg2) . args)

  [If a previous cleanup issue prohibited NIL as a non-last argument
   then ignore the (NCONC NIL . args) case.]

 (NSUBSTITUTE new-object old-object sequence ...)
 (NSUBSTITUTE-IF new-object test sequence ...)
  is required to SETF any CAR (if SEQUENCE is a list) or VREF (if it's
  a vector) of SEQUENCE which is required to be replaced with
  NEW-OBJECT.  If SEQUENCE is a list, it none of the CDRs of the
  top-level list may be modified.  These functions, therefore, may be
  used in for-effect-only positions in code (some may find this
  stylistically distasteful, though).

 Note: The above clarifications are not intended as complete functional
 descriptions. They are intended to augment (rather than to replace)
 other descriptions already in effect.

Test Cases:

 For GETF...

    (SETQ FOO (LIST 'A 'B 'C 'D 'E 'F))    ==> (A B C D E F)
    (SETQ BAR (CDDR FOO))                  ==> (C D E F)
    (REMF FOO 'C)
    BAR				           ==> ??

    In Symbolics Common Lisp, BAR holds (C D E F).
    CLtL allows other interpretations. eg, BAR might hold
    (C), (NIL), (C NIL) or (C D).
    Under this proposal, any of these interpretations (and others as well)
    would still be valid

 For DELETE...

    (SETQ FOO (LIST 'A 'B 'C))   ==> (A B C)
    (SETQ BAR (CDR FOO))         ==> (B C)
    (SETQ FOO (DELETE 'B FOO))   ==> (A C)
    BAR                          ==> ??
    (EQ (CDR FOO) (CAR BAR))     ==> ??

    In Symbolics Common Lisp, these last two expressions return ((C)) and T.
    Under this proposal, either of these interpretations (and others
    as well) would be valid.

 For NCONC...

    (SETQ FOO (LIST 'A 'B 'C 'D 'E)
	  BAR (LIST 'F 'G 'H 'I 'J)
	  BAZ (LIST 'K 'L 'M)) => (K L M)
    (SETQ FOO (NCONC FOO BAR BAZ)) => (A B C D E F G H I J K L M)
    FOO => (A B C D E F G H I J K L M)
    BAR => (F G H I J K L M)
    BAZ => (K L M)

    (SETQ FOO (LIST 'A 'B 'C 'D 'E)
	  BAR (LIST 'F 'G 'H 'I 'J)
	  BAZ (LIST 'K 'L 'M)) => (K L M)
    (SETQ FOO (NCONC NIL FOO BAR NIL BAZ)) => (A B C D E F G H I J K L M) 
    FOO => (A B C D E F G H I J K L M)
    BAR => (F G H I J K L M)
    BAZ => (K L M)


Rationale:

 Implementations already vary widely on their implementation techniques
 for these functions. This effectively clarifies the status quo, making
 it more clear to programmers what they may rely upon in portable code.

 In the case of NCONC, however, the precise definition is useful because
 it is what users expect, it is how NCONC has been defined for many
 years, and it is how current implementations generally work.  It may
 not always be the most efficient way (e.g. it may result in invisible
 pointers in CDR-coded implementations), but callers of NCONC probably
 use it specifically for its precise side effects.

 In the case of NSUBSTITUTE, this seems like the only reasonable
 implementation mechanism, and there doesn't seem to be a reason not to
 guarantee it.

Current Practice:

 All valid implementations are believed to comply with the vague
 definitions.  Symbolics Genera 7.2 and Sun Common Lisp 2.1.3 appear to
 conform to the NCONC spec.

Cost to Implementors:

 None. This is probably the status quo for most implementors.  If there
 are any implementations that don't implement NCONC and NSUBSTITUTE as
 above (which I doubt) they will have to be changed.

Cost to Users:

 This change would not affect programs coded with "good programming
 practice".  That is, only programs which rely on currently undocumented
 features would be in any danger of breaking.  In fact, those programs
 are already in such danger, and this change to the documentation would
 just publicize it.  The clarification would -encourage- good programming
 practice by warning people to only obey the published contract of the
 above-mentioned functions.

 There is, however, no automatic technique for making this check for
 programs already in error. Bugs due to unexpected side-effects are in
 general among the hardest to reckon with.

Cost of Non-Adoption:

 Programmers may naively believe there is only one possible or reasonable
 implementation of these functions. Some implementors may shy away from
 reasonable optimizations out of a paranoid belief that deviating from 
 some vague, unspoken rules will lead to programmer unrest. Making these
 things explicitly vague clarifies the implementor's rights in a way that
 permits numerous useful optimizations.

Benefits: 

 Users would be discouraged from taking advantage of subtle details
 of these destructive operations because such details would be explicitly
 not guaranteed to be portable.

 Implementations can improve performance of many of the above-mentioned
 functions when they are not under the constraint to implement them
 in a highly constrained fashion. For example, in Symbolics systems,
 DELETE of a cdr-coded list could use the implementation primitive
 %CHANGE-LIST-TO-CONS rather than RPLACD to avoid creating forwarding
 pointers.

 Garbage collection effectiveness can also be improved. For example,
 all of the destructive operations which remove objects (eg, REMF)
 could remove CAR pointers to removed objects which are more volatile
 than the list itself, assisting the garbage collector and thereby
 improving memory usage and paging performance.

 Tightening the definition of NCONC and NSUBSTITUTE permits users to
 predict their programs' behavior more precisely.

Non-Benefits:

 Users who inadvertently depend on side-effect behavior may be rudely
 surprised when moving between implementations.

 Compatibility with older Lisp dialects is diminished.

 Implementors have less flexibility in implementing NCONC efficiently.
 This is true of NSUBSTITUTE, but this is less likely to cause problems.

Performance Impact:

 Metering in Symbolics test  systems have shown that there are substantial
 performance gains to be had by allowing implementations flexibility in
 these areas.

 In the case of NCONC, this implementation flexibility, and hence
 potential performance improvements, is sacrificed.

 If anyone ever invents CAR-coding, the required implementation of
 NSUBSTITUTE could be a performance hindrance.

Aesthetics:

 Most of these functions implement abstract operations. For example,
 REMPROP implements an abstract operation on a "property list".
 Proper language design should not encourage people to delve below the
 level of abstraction into the nitty gritty.

 NCONC is a "less abstract" function than the rest of the functions
 described above.  It is usually used precisely because of the way it
 interacts with list implementation.  Similarly for NSUBSTITUTE.

Discussion:

 Andre's original version of this proposal pushed for explicitly vague
 descriptions of these functions' side-effect behavior.  He believes
 that if users want more predictability from these functions, they
 should write private variants that implement whatever predictability
 they require. 

 Pitman originally opposed this position because he weighed portability
 a higher concern. Since the original discussion, however, his views on
 how to resolve this priority have been refined, and he now believes
 that leaving things vague is appropriate. As such, he now supports what
 is effectively Andre's original proposal.

 Pitman and Andre supported version 4.  [I don't know how they feel
 about v6 -- Barmar].

 Moon supports version 6.

∂23-Mar-89  1504	X3J13-mailer 	issue COMPILER-DIAGNOSTICS, version 10   
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89  12:13:08 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA11279; Thu, 23 Mar 89 13:13:03 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA12687; Thu, 23 Mar 89 13:13:00 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903232013.AA12687@defun.utah.edu>
Date: Thu, 23 Mar 89 13:12:58 MST
Subject: issue COMPILER-DIAGNOSTICS, version 10
To: x3j13@sail.stanford.edu

This writeup has also had some minor changes to error terminology
made, under the section on warnings (2b).  I've also added a couple of
notes to the discussion section on issues that have come up but that
have not yet been resolved.

Forum:		Compiler
Issue:		COMPILER-DIAGNOSTICS
References:	CLtL p. 438-439, 62, 69, 160, 161
		Condition System, Revision #18
	    	S:>KMP>cl-conditions.text.34
	    	Issue GC-MESSAGES
	    	Issue RETURN-VALUES-UNSPECIFIED
	    	Issue COMPILER-VERBOSITY
		Issue CONDITION-RESTARTS
Category:	CLARIFICATION, ENHANCEMENT
Edit History:   V1, 15 Oct 1988, Sandra Loosemore
	    	V2, 19 Oct 1988, Sandra Loosemore (minor fixes)
	    	V3, 25 Oct 1988, Sandra Loosemore (input from Pitman & Gray)
	    	V4, 01 Nov 1988, Sandra Loosemore (fix typos)
	   	V5, 15 Dec 1988, Dan L. Pierson   (new condition types)
	   	V6, 15 Dec 1988, Sandra Loosemore (additions, fix wording)
	    	V7, 16 Dec 1988, Dan L. Pierson   (minor cleanup)
		V8, 07 Jan 1989, Sandra Loosemore (expand discussion)
		V9, 26 Jan 1989, Sandra Loosemore (simplify)
		V10, 22 Mar 1989, Sandra Loosemore (error terminology)
Status:		Ready for release
     
Problem Description:

It is unclear whether various diagnostics issued by the compiler are 
supposed to be true errors and warnings, or merely messages.

In some implementations, COMPILE-FILE handles even serious error
situations (such as syntax errors) by printing a message and then
trying to recover and continue compiling the rest of the file, rather
than by signalling an error.  While this user interface style is just
as acceptable as invoking the debugger, it means that a normal return
from COMPILE-FILE does not necessarily imply that the file was
successfully compiled.

Many compilers issue warnings about programming style issues (such as
binding a variable that is never used but not declared IGNORE).
Sometimes these messages obscure warnings about more serious problems,
and there should be some way to differentiate between the two.  For
example, it should be possible to suppress the style warnings.

Also, neither CLtL nor issue RETURN-VALUES-UNSPECIFIED states what the 
return value from COMPILE-FILE should be.


Proposal COMPILER-DIAGNOSTICS:USE-HANDLER:

(1) Introduce a new condition type, STYLE-WARNING, which is a subtype
    of WARNING.

(2) Clarify that ERROR and WARNING conditions may be signalled within 
    COMPILE or COMPILE-FILE, including arbitrary errors which may 
    occur due to compile-time processing of (EVAL-WHEN (COMPILE) ...) 
    forms or macro expansion.

    Considering only those conditions signalled -by- the compiler (as
    opposed to -within- the compiler),

    (a) Conditions of type ERROR may be signalled by the compiler in
        situations where the compilation cannot proceed without
        intervention.

        Examples:
	    file open errors
   	    syntax errors

    (b) Conditions of type WARNING may be signalled by the compiler in 
        situations where the standard explicitly states that a warning must,
        should, or may be signalled; and where the compiler can determine 
        that a situation with undefined consequences or that would cause
        an error to be signalled would result at runtime.

        Examples:
	    violation of type declarations
	    SETQ'ing or rebinding a constant defined with DEFCONSTANT
	    calls to built-in Lisp functions with wrong number of arguments
	        or malformed keyword argument lists
	    referencing a variable declared IGNORE
	    unrecognized declaration specifiers

    (c) The compiler is permitted to signal diagnostics about matters of
        programming style as conditions of type STYLE-WARNING.  Although 
        STYLE-WARNINGs -may- be signalled in these situations, no 
        implementation is -required- to do so.  However, if an 
        implementation does choose to signal a condition, that condition 
        will be of type STYLE-WARNING and will be signalled by a call to 
        the function WARN.

        Examples:
	    redefinition of function with different argument list
	    calls to function with wrong number of arguments
	    unreferenced local variables not declared IGNORE
	    declaration specifiers described in CLtL but ignored by 
	        the compiler

(3) Require COMPILE and COMPILE-FILE to handle the ABORT restart by
    aborting the smallest feasible part of the compilation.  State that
    both COMPILE and COMPILE-FILE are allowed to establish a default
    condition handler.  If such a condition handler is established,
    however, it must first resignal the condition to give any
    user-established handlers a chance to handle it.  If all user error
    handlers decline, the default handler may handle the condition in an
    implementation-specific way; for example, it might turn errors into
    warnings.

(4) Specify that COMPILE-FILE returns two values.  The first value
    is the truename of the output file, or NIL if the file could not be
    created.  The second value is T if the file was compiled without
    errors, or NIL if errors were signalled during compilation.


Rationale:

Introducing the STYLE-WARNING condition allows handlers to distinguish
between potentially serious problems and mere kibitzing on the part of
the compiler.

Requiring any condition handlers established by the compiler to resignal
the condition before proceeding with any implementation-specific action
gives user error handlers a chance to override the compiler's default
behavior.  For example, the user error handler could invoke a restart
such as ABORT or MUFFLE-WARNING.

Requiring the compiler to handle the ABORT restart reflects what
several implementations already do (although probably not using this
mechanism).  The intent of the wording is to allow an implementation
to abort the entire compilation if it is not feasible to abort a
smaller part.

Requiring a second success-p value to be returned from COMPILE-FILE
gives the user some indication of whether there were serious problems
encountered in compiling the file.


Test Case/Example:

Here is an example of how COMPILE-FILE might set up its condition
handlers.  It establishes an ABORT restart to abort the compilation
and a handler to take implementation-specific action on ERROR
conditions.  Note that INTERNAL-COMPILE-FILE may set up additional
ABORT restarts.

    (defvar *output-file-truename* nil)

    (defun compile-file (input-file &key output-file)
      (let ((*output-file-truename*    nil)
 	    (errors-detected           nil))
	(with-simple-restart (abort "Abort compilation.")
	  (handler-bind ((error  #'(lambda (condition)
				     (setq errors-detected t)
				     (signal condition)
				     ...)))
	    (internal-compile-file input-file output-file)))
	(values *output-file-truename*
		errors-detected)))



Current Practice:

No implementation behaves exactly as specified in this proposal.

In VaxLisp, COMPILE-FILE handles most compile-time errors without
invoking the debugger.  (It gives up on that top-level form and moves on
to the next one.)  Instead of signalling errors or warnings, it simply
prints them out as messages.

In Lucid Common Lisp, COMPILE-FILE invokes the debugger when it encounters
serious problems.  COMPILE-FILE returns the pathname for the output file.

Symbolics Genera usually tries to keep compiling when it encounters errors;
so does Symbolics Cloe.

On the TI Explorer, the compiler tries to catch most errors and turn
them into warnings (except for errors on opening a file), but the user
can change special variable COMPILER:WARN-ON-ERRORS to NIL if he wants
to enter the debugger on an error signalled during reading, macro
expansion, or compile-time evaluation.  The true name of the output
file is returned as the first value.  A second value indicates whether
any errors or warnings were reported.

IIM Common Lisp's compiler handles errors using a resignalling mechanism
similar to what is described here.


Cost to implementors:

The cost to implementors is not trivial but not particularly high.  This
proposal tries to allow implementations considerable freedom in what
kinds of conditions the compiler must detect and how they are handled,
while still allowing users some reasonably portable ways to deal with
compile-time errors.


Cost to users:

This is a compatible extension.  This proposal may cause users to see
some small differences in the user interface to the compiler, but
implementations already vary quite widely in their approaches.  Some
users will probably have to make some minor changes to their code.

Adding the STYLE-WARNING type may cause conflicts with programs
already using that name.


Benefits:

Users are given a way to detect and handle compilation errors, which
would simplify the implementation of portable code-maintenance
utilities.  The behavior of the compiler in error situations is made
more uniform across implementations.


Discussion:

The issue of whether the compiler may print normal progress messages
is discussed in detail in a separate issue, COMPILER-VERBOSITY.

Explicit calls to ERROR don't really justify warnings to be signalled
at compile-time, but we assume implementors have some common sense
about when it's appropriate to do so.

Proposal CONDITION-RESTARTS:PERMIT-ASSOCIATION would make it illegal
for conditions to be resignalled.  If that proposal is accepted, the
wording here would have to be changed to indicated that the compiler's
condition handler makes a copy of the condition and signals that.

Moon says:

  I think [requiring the ABORT restart to be handled] is wrong.  The only
  documentation of the ABORT restart that I could find says
  
    The purpose of the ABORT restart is generally to allow return to the
    innermost ``command level.''
  
  I agree with this, and I believe it means that it is wrong for any
  function other than one that establishes a read-eval-print loop or
  a command-level to establish an ABORT restart.  It would be useful
  to have some restart that aborts a portion of the compilation, but
  it should be given some other name.
-------

∂23-Mar-89  1503	X3J13-mailer 	issue COMPILED-FUNCTION-REQUIREMENTS, version 5    
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89  11:56:51 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA10754; Thu, 23 Mar 89 12:56:42 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA12677; Thu, 23 Mar 89 12:56:39 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903231956.AA12677@defun.utah.edu>
Date: Thu, 23 Mar 89 12:56:37 MST
Subject: issue COMPILED-FUNCTION-REQUIREMENTS, version 5
To: x3j13@sail.stanford.edu

Some people have spoken up in favor of restoring the proposal FLUSH
that was present in an earlier version of this proposal, so here it is
(combined with a further change to COMPILE that some people have
requested).  It's my impression that proposal FLUSH has more support
now than it used to.

Forum:		Compiler
Issue:		COMPILED-FUNCTION-REQUIREMENTS
References:	CLtL p. 32, 76, 112, 143, 438-439
		Issue FUNCTION-TYPE (passed)
		Issue COMPILER-LET-CONFUSION
		Issue EVAL-WHEN-NON-TOP-LEVEL
		Issue LOAD-TIME-EVAL (passed)
		Issue COMPILE-ENVIRONMENT-CONSISTENCY
		Issue COMPILE-ARGUMENT-PROBLEMS
Category:	CLARIFICATION
Edit History:   V1, 3 Jan 1989 Sandra Loosemore
		V2, 10 Jan 1989, Sandra Loosemore (additional proposal)
		V3, 10 Feb 1989, Sandra Loosemore (new proposal)
		V4, 11 Mar 1989, Sandra Loosemore (fix wording to agree
			with other pending proposals)
		V5, 23 Mar 1989, Sandra Loosemore (restore proposal FLUSH)
Status:		Ready for release


Problem Description:

There is confusion about what functions might be or must be of type
COMPILED-FUNCTION, and what attributes must be true of
COMPILED-FUNCTIONs.  Is the distinction between COMPILED-FUNCTIONs and
other functions only one of representation, or can user programs infer
anything about COMPILED-FUNCTIONs?  Are implementations required to
distinguish between compiled and non-compiled functions?

CLtL defines a COMPILED-FUNCTION as "a compiled code object".  (Issue
FUNCTION-TYPE says only that COMPILED-FUNCTION must be a subtype of
FUNCTION.)  Although it is not explicitly stated, CLtL implies that
compiled code must conform to certain rules; in particular, it states
that all macros are expanded at compile time, and specifies different
behavior for the COMPILER-LET and the EVAL-WHEN special forms
depending on whether they are interpreted or compiled.

The description of COMPILE in CLtL says that "a compiled-function object
[is] produced".  It is not clear to everyone whether this implies that
COMPILED-FUNCTION-P must be true of such functions.  CLtL says nothing
about whether functions defined in files compiled with COMPILE-FILE and
subsequently loaded must be of type COMPILED-FUNCTION.

The proposals presented below present a simple model of the
compilation process.  A minimal compiler could be implemented to
perform a code walk to apply the indicated transformations to the
function source code.  Of course, most compilers will perform other
transformations as well, such as translating the Lisp source code into
a representation that is more compact or which can be executed more
efficiently.


Proposal COMPILED-FUNCTION-REQUIREMENTS:TIGHTEN:

(1) Clarify that if a function is of type COMPILED-FUNCTION, the
    following are guaranteed about the function:

    - All macro calls appearing lexically within the function have 
      already been expanded and will not be expanded again when the
      function is called.  (See CLtL p. 143.)  The process of
      compilation effectively turns MACROLET and SYMBOL-MACROLET
      constructs into PROGNs with all instances of the local macros
      in the body fully expanded.

    - The compiler must capture declarations to determine whether
      variable bindings and references appearing lexically within 
      the function are to be treated as lexical or special.

    - COMPILER-LETs nested lexically within the function will not bind 
      any variables when the function is called (CLtL p. 112).  Again,
      the process of compilation effectively turns COMPILER-LET 
      constructs into PROGNs with all macros in the body fully expanded.

    - Lexically nested EVAL-WHENs have been processed as stated in
      proposal EVAL-WHEN-NON-TOP-LEVEL; either the body is treated as
      an implicit PROGN or as the constant NIL.

    - If the function contains lexically nested LOAD-TIME-VALUE forms,
      these have already been pre-evaluated and will not be evaluated
      again when the function is called.

(2) Implementations are free to classify all functions as 
    COMPILED-FUNCTIONs, provided that all functions satisfy the criteria
    listed in item (1).  It is also permissible for functions that are
    not COMPILED-FUNCTIONs to satisfy the above criteria.

(3) Clarify that COMPILE always produces an object of type 
    COMPILED-FUNCTION.  Clarify when functions are defined in a 
    file which is compiled with COMPILE-FILE, and the compiled file is
    subsequently LOADed, objects of type COMPILED-FUNCTION result.


  Rationale:

  This proposal allows users to count on COMPILE and COMPILE-FILE always
  producing objects that are COMPILED-FUNCTION-P.

  It assigns some specific properties to compiled functions.  Users would
  be able to rely on any function which is of type COMPILED-FUNCTION having
  really been (at least partially) compiled.

  It also states what many people believe to be the minimum functionality 
  required of a compiler.


Proposal COMPILED-FUNCTION-REQUIREMENTS:TIGHTEN-COMPILE:

(1) Clarify that functions produced by COMPILE, or defined in a file
    produced by COMPILE-FILE which has been subsequently LOADed, must
    satisfy the same requirements listed in section (1) of proposal
    TIGHTEN.

(2) Clarify that COMPILE always produces an object of type 
    COMPILED-FUNCTION.  Clarify when functions are defined in a 
    file which is compiled with COMPILE-FILE, and the compiled file is
    subsequently LOADed, objects of type COMPILED-FUNCTION result.


  Rationale:

  This proposal allows users to count on COMPILE and COMPILE-FILE always
  producing objects that are COMPILED-FUNCTION-P.

  It also states what many people believe to be the minimum functionality 
  required of a compiler.
  
  However, it allows functions that have not been compiled also to be of
  type COMPILED-FUNCTION.  For implementations that do not use different
  representations for interpreted and compiled functions, it would still
  allow COMPILED-FUNCTION and FUNCTION to be synonymous, even if
  interpreted functions do not satisfy the requirements for compilation.


Proposal COMPILED-FUNCTION-REQUIREMENTS:FLUSH:

(1) Remove the type specifier COMPILED-FUNCTION and the predicate
    COMPILED-FUNCTION-P from the language.

(2) Clarify that functions defined in a file produced by COMPILE-FILE
    which has been subsequently LOADed, must satisfy the same
    requirements listed in section (1) of proposal TIGHTEN.

(3) Remove the language from proposal COMPILE-ARGUMENT-PROBLEMS:CLARIFY
    that says "it is an error" to try to COMPILE a function that was
    defined interpretively in a non-null lexical environment.
    Instead, state that if COMPILE cannot compile the function, it
    should simply behave as an identity operation.

  Rationale:

  Distinguishing between compiled and non-compiled functions is of
  little use to portable programs.

  Some people believe that it should be valid to call COMPILE on any
  function, and that it should be legitimate for COMPILE to do nothing.


Current Practice:

It appears that most implementations currently distinguish compiled
versus non-compiled functions on the basis of representation.  It seems
unlikely that any implementation would have problems satisfying the
stated minimum requirements for compilation.

Lucid uses the same representation for both compiled and non-compiled
functions, except there is a bit in the header used to distinguish them.

A-Lisp uses the same representation for both compiled and interpreted
functions and currently labels them both as COMPILED-FUNCTION, but the
implementation of COMPILED-FUNCTION-P could be easily fixed to
distinguish "real" compiled functions.

On the TI Explorer, the COMPILE function can return an object of
either type COMPILED-FUNCTION or LEXICAL-CLOSURE, where the latter
consists of two components -- an environment and a COMPILED-FUNCTION.
There is confusion about whether microcoded functions should be
considered compiled or not.


Cost to implementors:

Unknown, but probably small for either proposal.  Proposal 
TIGHTEN-COMPILE is probably most consistent with current practice.


Cost to users:

Probably minimal.  Since the COMPILED-FUNCTION type specifier is
currently ill-defined, it is hard to imagine that existing programs
can portably rely on any interpretation of what it means that is
inconsistent with what is presented here.


Benefits:

The specification of what the compiler must do is made more explicit.


Discussion:

The FIXNUM and BIGNUM types were also defined in CLtL solely on the
basis of distinguished representations, and that this definition has
proved inadequate for just about all portable usages of these type
specifiers.  Defining COMPILED-FUNCTION solely on the basis of
distinguished representation seems like a bad idea.

David Gray notes:

  We make good use of the type COMPILED-FUNCTION in our implementation,
  but all of the accessor functions for objects of that type are
  non-standard, which makes me wonder if it might be best to just remove
  this type from the standard along with BIGNUM.

One use of the COMPILED-FUNCTION type is in declarations.  A-Lisp and
Lucid, for example, can compile FUNCALL more efficiently if it can be
determined that the function is of type COMPILED-FUNCTION.  However,
in order for such declarations to be really useful, there should be a
way to construct an object which is guaranteed to be of type
COMPILED-FUNCTION.  Both of the proposals presented require COMPILE
and COMPILE-FILE to construct compiled functions.

Moon says:

  I much prefer the option FLUSH...
  This type has no portable meaning and never should have existed.

Pierson says:

  What I (and believe Kent) want is a guarantee that [COMPILE] won't
  signal an error; if nothing else works COMPILE will simply apply
  #'IDENTITY to the symbol's function.  Specifically, it should be
  legal and safe to attempt to speed up my current program(s) by
  doing:

    (DO-SYMBOLS (SYM <my-package>)
    	(WHEN (FBOUNDP SYM) (COMPILE SYM)))

-------

∂23-Mar-89  1512	X3J13-mailer 	issue COMPILER-LET-CONFUSION, version 8  
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89  15:07:47 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA17346; Thu, 23 Mar 89 16:07:29 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA12792; Thu, 23 Mar 89 16:07:25 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903232307.AA12792@defun.utah.edu>
Date: Thu, 23 Mar 89 16:07:23 MST
Subject: issue COMPILER-LET-CONFUSION, version 8
To: x3j13@sail.stanford.edu

This version fixes the bug in the example code that was pointed out
earlier, and clarifies the relation between COMPILER-LET and
DEFINE-OPTIMIZER.

There has been some discussion that COMPILER-LET might be implemented
by storing its variable bindings in the lexical environment.  Some of
us think that this would result in a significant change to the
semantics of COMPILER-LET that would be inappropriate to pursue at
this time, and in any case there hasn't been a proposal submitted yet
that addresses all of the issues involved.

Issue:		COMPILER-LET-CONFUSION
Forum:	        Compiler
References:	CLtL p. 112
		Issue DEFINE-OPTIMIZER
Category:	CHANGE
Edit History:   V1, 27 Sep 1988, Sandra Loosemore (initial version)
                V2, 04 Oct 1988, Sandra Loosemore (add another example)
		V3, 31 Oct 1988, Sandra Loosemore (only proposal ELIMINATE)
	        V4, 08 Jan 1989, Kent M. Pitman (new alternative)
		V5, 09 Jan 1989, Sandra Loosemore (discussion)
		V6, 08 Mar 1989, Sandra Loosemore (general updating)
		V7, 13 Mar 1989, Sandra Loosemore (fix bug from V6)
		V8, 23 Mar 1989, Sandra Loosemore (fix another bug, add
					to discussion)

Problem Description:

 The description of the COMPILER-LET special form in CLtL is confusing
 to many people.  There are no examples provided to make it clear how it
 is supposed to be used. The only description which is offered is overly
 concrete, which has led to confusion about the intent of COMPILER-LET,
 and about its implementability.
 
 The intent of COMPILER-LET was to permit information to be communicated
 between macros by use of dynamic variables at macroexpansion time.
 It was not necessary to the intended uses of COMPILER-LET that such
 variables ever be bound at execution time.  
 
 Unfortunately, probably because some implementations did not primitively
 support COMPILER-LET at the time CLtL was written, an exception was 
 permitted to make COMPILER-LET `more or less work' in interpreters: 
 the COMPILER-LET variables were permitted to be bound at execution time.
 The problem was further compounded by the fact that CLtL presented this
 exception as part of COMPILER-LET's contract rather than as an 
 implementation note, and by the fact that no examples of actually using
 COMPILER-LET correctly are provided.

 One particular case where problems have resulted is a situation like
   (compiler-let ((*v* 1))
     #'(lambda () (m)))
 where M is a macro that refers to *V*.  In some implementations, M is
 not macroexpanded until the dynamic extent of the *V* binding has
 ended.
 
 Subtle bugs can be introduced because of the different handling of the
 variable bindings in the interpreter and the compiler.  In compiled
 code, the bindings are only lexically visible during the expansion of
 macros at compile time, while in interpreted code the bindings have
 dynamic scope and may also be seen during ordinary evaluation if
 evaluation and macroexpansion happen "in parallel".
 
 Further compatibility problems can result from the value forms being
 evaluated in a null lexical environment in the compiler and the ordinary
 lexical environment in the interpreter.
 
Background and Analysis:

 It should be clear up front that COMPILER-LET is not computationally
 essential. Most (if not all) uses of it can be rewritten using MACROLET
 or SYMBOL-MACROLET.

 A typical use of COMPILER-LET might be:

  (defvar *local-type-declarations* '())
     
  (defmacro local-type-declare (declarations &body forms)
    `(compiler-let ((*local-type-declarations* 
		      (append ',declarations *local-type-declarations*)))
       ,@forms))
     
  (defmacro typed-var (var)
    (let ((type (assoc var *local-type-declarations*)))
      (if type `(the ,(cadr type) ,var) var)))
     
  (defun f (x y)
    (local-type-declare ((x fixnum) (y float))
      (+ (typed-var x) (typed-var y))))
    

 The same thing could be accomplished using MACROLET:
  
  (defmacro local-type-declare (declarations &body forms)
    (local-type-declare-aux declarations forms))
    
  (defmacro typed-var (var) var)

  (eval-when (eval compile load)
    (defun local-type-declare-aux (declarations forms)
      `(macrolet ((typed-var (var)
		    (let ((type  (assoc var ',declarations)))
		      (if type `(the ,(cadr type) ,var) var)))
		  (local-type-declare (new-declarations &body new-forms)
		    (local-type-declare-aux
		      (append new-declarations ',declarations)
		      new-forms)))
	 ,@forms)))


 A further alternative would be to use SYMBOL-MACROLET (this particular
 implementation assumes that issue DEFINING-MACROS-NON-TOP-LEVEL passes):

  (let ((temp  (gensym)))
    (defmacro local-type-declare (declarations &body forms &environment env)
      `(symbol-macrolet ((,temp  ',(append declarations
					  (symbol-macro-value temp env))))
         ,@forms))
    (defmacro typed-var (var &environment env)
      (let ((type  (assoc var (symbol-macro-value temp env))))
	(if type `(the ,(cadr type) ,var) var)))
    )
			  
  (defun symbol-macro-value (symbol env &optional default)
    (multiple-value-bind (expansion macro-p) (macroexpand symbol env)
      (if macro-p (eval expansion) default)))

 
 Opinion is divided as to which is more understandable.  Some
 people find the COMPILER-LET idiom more understandable (assuming that
 it can be made to work consistently in compiled and interpreted
 code), while others find it just as natural to use MACROLET or 
 SYMBOL-MACROLET.

 The issues are these:

  - Is it possible to implement COMPILER-LET in a usefully consistent
    way in all implementations?

  - Are the benefits of providing a useful and compatible implementation
    of COMPILER-LET worth any associated cost?

 Two proposals are presented below:

  - Option REPAIR argues that COMPILER-LET provides interesting
    functionality that can be implemented in a manner that is usefully
    consistent across implementations, and that the associated cost
    is low enough for it to be worthwhile to do so.

  - Option ELIMINATE argues that COMPILER-LET complicates the language
    and that providing this construct is not worth the associated 
    implementation cost.


Proposal (COMPILER-LET-CONFUSION:REPAIR):

  Strike the existing definition of COMPILER-LET. Redefine it as follows:
  
  COMPILER-LET						  [Special form]
  
    COMPILER-LET is similar to LET, but it always makes special 
    bindings and makes those bindings visible only during 
    macroexpansion of forms in the body, not during the runtime
    execution of those forms.  

    If proposal DEFINE-OPTIMIZER:NEW-FACILITY is accepted, then
    optimizer functions are also executed in a dynamic environment
    in which COMPILER-LET bindings are visible.

    The intent is that some macros might macroexpand into calls to
    COMPILER-LET in which the body would the contain references to
    macros which access the variables in the COMPILER-LET.
  
    The initial value forms of the bindings, if any, are always 
    evaluated in a null lexical context, regardless of whether the
    COMPILER-LET expression is being interpreted or compiled.
  
    The initial value forms of the bindings, if any, are evaluated in
    a dynamic context where the bindings of any lexically enclosing
    COMPILER-LET are visible, and where dynamic execution-time 
    environment may or may not be visible.
  
    Implementation Note: Permitting the execution-time dynamic
    environment to be visible when initializing COMPILER-LET variables
    is a concession to some interpreters which may have to do this in
    order to keep the cost down. Where feasible, implementors should
    try not to make the runtime environment visible.

  Rationale:

    This gives a consistent description of COMPILER-LET which separates
    issues of intent from those of implementation in a way that makes it
    possible for portable code to make serious use of it, and which does
    not force gratuitous incompatibilities between interpreters and
    compilers.

    This description of COMPILER-LET can be implemented without undue
    cost by all implementations. See "Cost to Implementors" for details.

  Cost to Implementors:

    Modest, but nontrivial in some implementations.

    In compiled code, and in interpreters doing a one-time semantic
    prepass, it should be fairly easy for COMPILER-LET to cause the 
    variables to get bound (using PROGV) during semantic analysis.

    In interpreters which do not do a semantic-prepass, it is necessary
    to fully macroexpand the body. Assuming the presence of a
    SYSTEM::MACROEXPAND-ALL primitive, the definition of COMPILER-LET
    could look like:
      (DEFMACRO COMPILER-LET (BINDINGS &BODY FORMS &ENVIRONMENT ENV)
        (SETQ BINDINGS ;; Assure no non-atom bindings
	      (MAPCAR #'(LAMBDA (BINDING) 
		          (IF (ATOM BINDING) (LIST BINDING) BINDING))
		      BINDINGS))
        (PROGV (MAPCAR #'CAR BINDINGS)
	       (MAPCAR #'(LAMBDA (BINDING) (EVAL (CADR BINDING))) BINDINGS)
	  (SYSTEM::MACROEXPAND-ALL `(PROGN ,@FORMS) ENV)))
    This reduces the problem of writing a program capable of doing a
    full macroexpansion. Many systems already have such a facility.
    Pitman wrote such a facility in Cloe Runtime in order support 
    SYMBOL-MACROLET (before it was christened a special form); it was
    about 750 lines of relatively straightforward, well-commented code.

  Cost to Users:

    Code currently depending on this feature is either non-existent or
    already not portable (due to wide variation in implementation 
    strategy for COMPILER-LET).

    Most users will probably be happy for any interpretation which offers
    them a future shot at portability.

    Some users have indicated they dislike interpreters which do a semantic
    prepass, because they like to be able to dynamically redefine macros
    while debugging.


Proposal (COMPILER-LET-CONFUSION:ELIMINATE):

  Remove COMPILER-LET from the language.
  
  Rationale:

    Some people think that having one less special form would simplify the
    language.  The revised COMPILER-LET semantics, which require
    COMPILER-LET to make special bindings which are only visible during
    expansion of macros which appear lexically within its body, are
    not shared by any other feature in the language, and require a
    fairly complex implementation technique.  There are other
    constructs which are strictly lexical that can be readily used
    to solve the same kinds of problems that COMPILER-LET is intended to
    be used for.

  Cost to Implementors:
  
    Minimal.  Implementations could continue to support COMPILER-LET as
    an extension.
  
  Cost to Users:
  
    Code currently depending on this feature is either non-existent or
    already not portable (due to wide variation in implementation 
    strategy for COMPILER-LET).

    People who use COMPILER-LET would have to rewrite their programs to use
    some other construct.  As discussed above, most uses of COMPILER-LET
    for communication between macros can be handled using MACROLET or
    SYMBOL-MACROLET, though some perspicuity may be lost in the process.


Current Practice:
  
 Some implementations have implemented the description in CLtL. 
 Users of those implementations (quite reasonably) can't figure how to 
 use COMPILER-LET and so don't use it much.

 Some implementations whose interpreters include a preprocessor to
 expand all macros have already implemented something similar to proposal
 COMPILER-LET-CONFUSION:REPAIR.  Users of such implementations
 probably use COMPILER-LET somewhat more often since it has an
 intelligible behavior, but their code is not portable since it relies
 on behaviors which are either contrary to or not guaranteed by CLtL.

Benefits:

 Either way, a potential area of incompatibility between compiled and
 interpreted code would be eliminated.

 Either way, a potential area of portability trouble would be very
 drastically reduced (in the case of the REPAIR option) or eliminated
 (in the case of the ELIMINATE option).

Discussion:

 Pitman strongly favors COMPILER-LET-CONFUSION:REPAIR.  He argues 
 against the idea of using MACROLET instead of COMPILER-LET, saying:

  This is a little misleading because it's like saying you can
  do without LET given that you have FLET. You can, but you lose some things
  in the process:
 
  Just as rewriting a LET using FLET might slow your computation, so too
  a rewrite of COMPILER-LET using MACROLET might slow things down. However,
  compilation speed is generally not weighted as heavily as execution speed
  by many people, so the loss of speed here may not be as important.
 
  Just as rewriting a LET using FLET might obscure the simplicity of your
  intent, so too rewriting COMPILER-LET using MACROLET might obscure your
  intent. You'd probably get used to recognizing idioms if you used it often
  enough. Certainly this would be true if you didn't have LET. However,
  COMPILER-LET is used less often, so not having it would mean that the
  code you wrote instead would be much harder to read because people
  wouldn't have the necessary familiarity with the idioms involved and so
  wouldn't always understand them.
 
 Sandra Loosemore responds:

  The argument that using MACROLET is more inefficient than COMPILER-LET
  is questionable.  Both of the suggested implementation techniques for
  COMPILER-LET involve considerable overhead.

  If COMPILER-LET were not part of the language, people wouldn't think in
  terms of rewriting COMPILER-LETs as MACROLETs; instead, they'd think of
  how to use MACROLET in the first place to solve their problems.  This
  is what people who now use implementations with broken COMPILER-LETs
  already do.  Since MACROLET is now used much more frequently than
  COMPILER-LET, that argues that people are much more familiar with 
  MACROLET idioms than COMPILER-LET idioms.

  Also, note that the intent of the revised COMPILER-LET definition is
  to make the binding only lexically visible within the body.  Using
  special binding for this purpose is troublesome.  Both the MACROLET
  and SYMBOL-MACROLET solutions are completely lexical and avoid all
  the problems associated with special binding.

Glenn Burke thinks it needs to be emphasized that the code-walker
mentioned in the REPAIR proposal does not need to be portable.  He
says:

  The present wording makes it sound like a piece of cake to do with
  portable code, when the reality is that a good fraction of CL cleanup
  effort has involved the lack of capability of producing such a beast.
  Without one or more of a number of proposals being accepted, a fully
  correct portable code walker cannot be built, in my belief.

  I object to the flippant attitude of just "presupposing" this
  "trivial" function which "we know how to do".

We have considered a number of other options on this issue, including
a variety of proposals that would redefine COMPILER-LET to store
information about the variable bindings in the lexical environment, and
either having MACROEXPAND-1 make the special bindings or provide a
function which could be used to access them directly.

Kent Pitman says:
  People have suggested that if it comes to making an incompatible change
  on this one, it's probably better to just remove the feature and let
  people continue to provide it compatibly where they think it's useful.
  Even though I think the COMPILER-SYMBOL-VALUE thing is technically
  doable, I find myself swayed by arguments that it's not the correct
  avenue for us to pursue at this time.

David Moon says:
  I think COMPILER-LET-CONFUSION:REPAIR should be split into four proposals.
  First, one that gives the general framework for repairing but doesn't
  say anything about how the interpreter implements COMPILER-LET, other
  than to say that an additional proposal is needed to cover that.  Then
  three proposals for how the interpreter implements COMPILER-LET:
   (1) The interpreter always does a "semantic pre-pass" like the compiler.
   (2) The interpreter expands all macros inside COMPILER-LET before
       evaluating any of the code inside COMPILER-LET.
   (3) COMPILER-LET passes the variable bindings to MACROEXPAND-1
       through the lexical environment, and the time when the interpreter
       expands macros is not changed.
-------

∂23-Mar-89  1523	X3J13-mailer 	issue CONSTANT-COLLAPSING, version 6
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89  15:22:35 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA12319; Thu, 23 Mar 89 13:55:55 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA12724; Thu, 23 Mar 89 13:55:52 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903232055.AA12724@defun.utah.edu>
Date: Thu, 23 Mar 89 13:55:51 MST
Subject: issue CONSTANT-COLLAPSING, version 6
To: x3j13@sail.stanford.edu

This issue has had some editorial changes made to it, to clarify the
terminology that it uses.  

Forum:		Compiler
Issue:		CONSTANT-COLLAPSING
References:	CLtL p. 78, 87
		Issue CONSTANT-MODIFICATION
		Issue CONSTANT-COMPILABLE-TYPES
		Issue EQUAL-STRUCTURE
		Issue QUOTE-SEMANTICS
Category:	CHANGE
Edit History:   V1, 07 Nov 1988, Sandra Loosemore
		V2, 12 Dec 1988, Sandra Loosemore
		V3, 03 Jan 1989, Sandra Loosemore
		V4, 06 Jan 1989, Sandra Loosemore
		V5, 11 Mar 1989, Sandra Loosemore
		V6, 22 Mar 1989, Sandra Loosemore (comments from Moon)
Status:		Ready for release


Problem Description:

CLtL states that an implementation is permitted to "collapse" or
coalesce constants appearing in code to be compiled if they are EQUAL.
The definition of EQUAL does not permit coalescing of more general
isomorphic data structures (such as arrays), which is often desirable.

This proposal deals only with changing the test which is used to
determine whether two constants may be coalesced.  Issue
QUOTE-SEMANTICS deals with whether coalescing may be performed only by
COMPILE-FILE, or by COMPILE and EVAL as well.  If proposal
QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE passes, then coalescing could be
performed on all constants.

This proposal uses the terms "source code", "compiled code", and
"similar as constants" that are defined in proposal
CONSTANT-COMPILABLE-TYPES:SPECIFY.

The term "coalesce" is defined as follows.  Suppose A and B are two
objects used as quoted constants in the source code, and that A' and
B' are the corresponding objects in the compiled code.  If A' and B'
are EQL but A and B were not EQL, then we say that A and B have been
coalesced by the compiler.


Proposal CONSTANT-COLLAPSING:GENERALIZE:

State that an implementation is permitted to coalesce constants
appearing in code to be compiled if and only if they are similar as
constants, unless the objects involved are of type SYMBOL, PACKAGE,
STRUCTURE, or STANDARD-OBJECT.


Rationale:

There is little reason why implementations should not be allowed to
perform more general collapsing of objects, since the arguments
against doing so also apply to collapsing of EQUAL objects, which
is already permitted.  The arguments for coalescing of EQUAL data
structures (primarily space reduction) also apply to coalescing of
data structures that are equivalent under a more general coalescing
predicate.

Objects of type SYMBOL and PACKAGE cannot be coalesced because the fact
that they are named, interned objects means they are already as
coalesced as it is useful for them to be.  Uninterned symbols could
perhaps be coalesced, but that was thought to be more dangerous than
useful.  Objects of type STRUCTURE and STANDARD-OBJECT could be
coalesced if a "similar as a constant" predicate were defined for them;
it would be a generic function.  Currently LOAD-OBJECTS only defines how
COMPILE-FILE and LOAD work together to construct an object in the
compiled code that is equivalent to the object in the source code,
and a different mechanism would have to be added to permit coalescence.


Current Practice:

Both PSL/PCLS and A-Lisp collapse isomorphic arrays and structures,
and certain other data types that are defined internally as structures
(RANDOM-STATEs, for example).  Lucid Common Lisp also uses a more
general coalescing predicate than EQUAL.


Cost to implementors:

For implementations that currently coalesce based on EQUAL or that do
no coalescing, there is no associated implementation cost.

For implementations that currently coalesce things that this proposal
forbids them to coalesce (such as STRUCTUREs or uninterned symbols),
the implementation cost is probably small.


Cost to users:

Programs that depend on objects not being coalesced except when they
are EQUAL may break under this proposal.  The only way one would be
able to detect that coalescing has taken place is if objects that were
not EQL in the source file become EQL after compilation; accessors on
the objects would return the same values regardless of whether or not
coalescing has taken place.


Benefits:

Collapsing of isomorphic arrays may lead to significant memory savings
in some applications.


Discussion:

This proposal depends heavily on issue CONSTANT-COMPILABLE-TYPES.

Some people believe that if the definition of EQUAL weren't "broken",
there wouldn't be any need for this proposal.

There is no inherent reason why the "coalescing predicate" must be the
same as the relationship used by the compiler/loader to construct
equivalent copies of objects of constants, but making the same rules
be applied in both situations simplifies the language somewhat.
-------

∂23-Mar-89  1521	X3J13-mailer 	issue DEFINING-MACROS-NON-TOP-LEVEL, version 9
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89  15:21:20 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA14332; Thu, 23 Mar 89 14:39:26 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA12751; Thu, 23 Mar 89 14:39:23 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903232139.AA12751@defun.utah.edu>
Date: Thu, 23 Mar 89 14:39:21 MST
Subject: issue DEFINING-MACROS-NON-TOP-LEVEL, version 9
To: x3j13@sail.stanford.edu

The part of this proposal that used to be item (3) has been moved to
issue EVAL-WHEN-NON-TOP-LEVEL.  It now has a new item (3) dealing with
MACROLET semantics.

Please consider this issue carefully.  It specifies some incompatible
changes to the treatment of macro functions, both for DEFMACRO and
MACROLET.  The changes to DEFMACRO are necessary for compatibility
with issue EVAL-WHEN-NON-TOP-LEVEL.  The changes to MACROLET are seen
as desirable for compatibility with the changes to DEFMACRO.

Forum:		Compiler
Issue:		DEFINING-MACROS-NON-TOP-LEVEL
References:	CLtL p. 66-70, 114, 143
		Issue EVAL-WHEN-NON-TOP-LEVEL
		Issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS
		Issue COMPILER-LET-CONFUSION
Category:	CLARIFICATION, ENHANCEMENT, CHANGE
Edit History:   6-May-88, V1 by Sandra Loosemore
		9-Jun-88, V2 by Sandra Loosemore
		12-Sep-88, V3 by Sandra Loosemore (fix garbled section 4)
                21-Sep-88, V4 by Sandra Loosemore (clarify section 5)
		16-Dec-88, V5 by Sandra Loosemore (major restructuring)
		31-Dec-88, V6 by Sandra Loosemore (wording clarifications)
		07-Jan-89, V7 by Sandra Loosemore (add example)
		09-Mar-89, V8 by Sandra Loosemore (more restructuring)
		22-Mar-89, V9 by Sandra Loosemore (add MACROLET stuff)
Status:		Ready for release


Problem Description:

CLtL leaves the interpretation of defining forms such as DEFMACRO and
DEFVAR that appear in other than top-level locations unclear.

On page 66, it is stated: "It is not illegal to use these forms at
other than top level, but whether it is meaningful to do so depends on
context.  Compilers, for example, may not recognize these forms
properly in other than top-level contexts".  At least one implementation 
has interpreted this to mean that it is permissible to simply refuse
to compile defining macros that do not appear at top-level.

A further problem is that CLtL p. 145 states that macro functions are
always defined in the null lexical environment.  These semantics would
require it to be a special form, not a macro, since there is no
possible macro expansion that has equivalent semantics under the
processing model presented in issue EVAL-WHEN-NON-TOP-LEVEL.  Under
that model, it ought to be possible for DEFMACRO to be implemented as
expanding into an EVAL-WHEN.  Furthermore, the macro function should
appear in a for-evaluation position in the expansion, such as
(function (lambda ...)).


Proposal DEFINING-MACROS-NON-TOP-LEVEL:ALLOW:

(1) Remove the language from p. 66 of CLtL quoted above.  Clarify that
while defining macros normally appear at top level, it is meaningful
to place them in non-top-level contexts and that the compiler must
handle them properly in all situations.  However, the compile-time side
effects described in issue COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS 
only take place when the defining macros appear at top-level.

(2) Remove the language from p. 145 of CLtL referenced above.  Clarify
that all defining macros which create functional objects (including
DEFMACRO, DEFTYPE, DEFINE-SETF-METHOD, and the complex form of
DEFSETF, as well as DEFUN) must ensure that those functions are
defined in the lexical environment in which the defining form appears.

(3) Change the description of MACROLET to indicate that the macro
functions it creates are defined in the lexical environment in which
the MACROLET form appears, and not the null lexical environment.
State that declarations and MACROLET and SYMBOL-MACROLET definitions
affect the local macro definitions in a MACROLET, but that the
consequences are undefined if the local macro definitions reference
any local variable or function bindings that are visible in that
lexical environment.


Rationale:

Items (1) and (2) make the rules for when defining macros cause
compile-time side effects to be exactly the same as the rules for when
(EVAL-WHEN (COMPILE) ...) causes compile-time evaluation.  This
provides a simple implementation technique.

Item (3) makes the handling of MACROLET macro definitions consistent
with DEFMACRO macro definitions.


Current Practice:

Most implementations do allow defining macros in non-top-level places.
However, the rules for when they cause compile-time side-effects are
not always the same as those for EVAL-WHEN.  This is the case in
Lucid Common Lisp, for example.

Lucid evaluates DEFMACRO macro functions in the lexical environment
in which the DEFMACRO appears, but always evaluates MACROLET macro
functions in the null lexical environment.


Cost to implementors:

Implementations that currently don't compile defining macros correctly
when they appear at non-top-level will have to be changed.

There will also be changes required to support compile-time definition
of functions in a non-null lexical environment.  These changes
are required to support defining macros such as DEFINE-SETF-METHOD
that require functional objects to be created at compile-time, as well
as to support the changes to DEFMACRO and MACROLET.  (Note that even
though defining macros cause compile-time evaluation only at
top-level, top-levelness does not necessarily imply a null lexical
environment under proposal EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL.)


Cost to users:

The changes to DEFMACRO and the other defining macros probably will
cause few problems for users.  Since CLtL didn't require non-top-level
defining macros to be meaningful, assigning them a meaning is a
compatible extension.

The changes to MACROLET may cause problems for users who have assumed
that, within local macro definitions, global function and variable
definitions are not shadowed by local function and variable bindings.
Code-walking programs will also have to be changed to reflect the new
semantics (see issue SYNTACTIC-ENVIRONMENT-ACCESS).


Benefits:

The notion of defining macros as being somehow special when they
appear at top-level is removed, since their behavior can be explained
using EVAL-WHEN as a primitive.  Allowing defining macros to appear
anywhere instead of restricting them to certain positions results in a
cleaner language design.


Discussion:

This proposal is consistent with the behavior specified in proposal
EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL.  In particular, if the compile
time side-effects for defining macros specified in proposal
COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS:CLARIFY are implemented using
EVAL-WHEN, the "right" compiler behavior for defining macros at
non-top-level will happen automatically.

The problems with compile-time definition of functions in a non-null
environment could be avoided by modifying proposal
DEFINING-MACROS-NON-TOP-LEVEL to remove the special treatment for
MACROLET, SYMBOL-MACROLET, and LOCALLY.
-------

∂23-Mar-89  1522	X3J13-mailer 	issue QUOTE-SEMANTICS, version 3    
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89  15:21:49 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA14563; Thu, 23 Mar 89 14:49:18 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA12765; Thu, 23 Mar 89 14:49:15 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903232149.AA12765@defun.utah.edu>
Date: Thu, 23 Mar 89 14:49:14 MST
Subject: issue QUOTE-SEMANTICS, version 3
To: x3j13@sail.stanford.edu

I have made some clarifications to the language in this issue, and
expanded the Cost to Implementors and Discussion sections.

Forum:		Compiler
Issue:		QUOTE-SEMANTICS
Subsumes:	Issue QUOTE-MAY-COPY
References:	CLtL p. 55, 78, 86, 143
		Issue CONSTANT-COLLAPSING
		Issue CONSTANT-COMPILABLE-TYPES
		Issue CONSTANT-CIRCULAR-COMPILATION
Category:	CLARIFICATION
Edit History:   V1, 22 Jan 1989, Sandra Loosemore
		V2, 13 Mar 1989, Sandra Loosemore (discussion)
		V3, 22 Mar 1989, Sandra Loosemore (suggestions from Moon)
Status:		Ready for release


Problem Description:

Is it permissible for COMPILE and EVAL to coalesce or copy constants?
Are there constraints upon what kinds of objects may appear as
constants in code processed by COMPILE or EVAL, similar to those for
COMPILE-FILE?

CLtL p86 states that (QUOTE <x>) simply returns <x>.  On p55 it is
mentioned that the only self-evaluating forms that may be copied are
numbers or characters.  It is also stated that an implementation is
permitted to collapse (or coalesce) EQUAL constants "appearing in code
to be compiled" (p78), which is defined to mean self-evaluating forms
or objects contained in a QUOTE form (without reference to whether the
form is processed by EVAL, COMPILE, or COMPILE-FILE).

Because of its nature as a file processor, COMPILE-FILE generally must
cause copies of constants to be constructed when the compiled code is
loaded.  In a number of existing Lisp implementations, COMPILE also
causes constant objects to be copied and/or coalesced.  There is also
at least one implementation where constants are copied by EVAL in some
circumstances.

In the proposals that follow, "copying" is used to mean the process of
constructing an object that is "similar as a constant" (as defined in
proposal CONSTANT-COMPILABLE-TYPES:SPECIFY), but not necessarily EQL,
to the original.

The term "coalescing" is defined in the writeup for issue 
CONSTANT-COLLAPSING.


Proposal QUOTE-SEMANTICS:NO-COPYING:

State that copying or coalescing of constants appearing in code
processed by EVAL and COMPILE is not permitted; the resulting program
must reference objects that are EQL to the corresponding objects in
the source code.  The constraints on what kinds of objects may appear
as constants (described in issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION) apply only to COMPILE-FILE.

  Rationale:

  This proposal is consistent with what many people think of as the
  "traditional" semantics for QUOTE.  It gives users maximum flexibility
  about what kinds of objects may appear as constants.


Proposal QUOTE-SEMANTICS:COPYING-ALLOWED-BUT-NO-CONSTRAINTS:

State that copying or coalescing of constants appearing in code
processed by EVAL and COMPILE is permitted.  Copying or coalescing may
only take place when the source code is "promoted" to being a program
by EVAL or COMPILE, not at runtime.  Function definitions are promoted
to being a program when the form enclosing the definition (e.g., a
FUNCTION or DEFUN form) is promoted.

Any object may validly appear as a constant in code processed by EVAL
or COMPILE.  The constraints on what kinds of objects may appear as
constants (described in issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION) apply only to COMPILE-FILE.  For data
types where proposal CONSTANT-COMPILABLE-TYPES:SPECIFY does not define
the notion of "similar as a constant", an implementation is permitted
to copy objects of that type only if it has extended "similar as a
constant" to include that type.

  Rationale:

  This proposal is the most consistent with the semantics stated in CLtL.
  It gives users maximum flexibility about what kinds of objects may
  appear as constants.

  Allowing constants to be coalesced or copied has advantages for
  memory management; for example, constants can be copied to read-only
  memory that does not need to be garbage-collected.


Proposal QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE:

State that copying or coalescing of constants appearing in code
processed by EVAL and COMPILE is permitted.  Copying or coalescing may
only take place when the source code is "promoted" to being a program
by EVAL or COMPILE, not at runtime.  Function definitions are promoted
to being a program when the form enclosing the definition (e.g., a
FUNCTION or DEFUN form) is promoted.

The constraints on what kinds of objects may appear as constants
(described in issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION) apply to EVAL and COMPILE as well as to
COMPILE-FILE.

  Rationale:

  This makes the rules for handling of constants consistent between
  EVAL, COMPILE, and COMPILE-FILE.  It gives implementors maximum 
  flexibility in handling constants in EVAL and COMPILE.

  Allowing constants to be coalesced or copied has advantages for
  memory management; for example, constants can be copied to read-only
  memory that does not need to be garbage-collected.


Current Practice:

Implementations in which COMPILE attempts to copy all constants
include PSL/PCLS, Utah Common Lisp, and Kyoto Common Lisp.  UCL and
KCL both implement COMPILE effectively as a combination of
COMPILE-FILE and LOAD.

In Lucid Common Lisp, constants are not normally copied by COMPILE,
but since COMPILE does coalesce constants, it may cause QUOTE to
return an object which is not EQL to the object which appeared in the
source code.

Symbolics Genera has COMPILE copy list, string, non-displaced array,
and (I-Machine only) closure constants, but Moon says he thinks this
is wrong.

There is known to be at least one implementation where expanding the
DEFUN macro causes all constants in the body of the function to be
copied.


Cost to implementors:

Proposal NO-COPYING would involve a significant cost in those
implementations where constants are now copied or coalesced by EVAL
and COMPILE.  The aspect that is likely to cause the most problems is
that, in some implementations, the garbage collector assumes that
constants referenced in compiled code have been copied to read-only
storage and do not need to be scanned or relocated.  Changing this
would require major changes to the internal representation of
functions, memory management strategy, and/or the implementation of
COMPILE.

Some implementations would also require substantial changes to support
proposal COPYING-ALLOWED-BUT-NO-CONSTRAINTS.  Implementations that
would have garbage collection problems under proposal NO-COPYING would
have the same problems under COPYING-ALLOWED-BUT-NO-CONSTRAINTS,
unless they can define a copying behavior that will correctly handle
objects of all possible datatypes.

Proposal SAME-AS-COMPILE-FILE has no adoption cost above what is
required to support issues CONSTANT-COMPILABLE-TYPES and
CONSTANT-CIRCULAR-COMPILATION.


Cost to users:

Proposals COPYING-ALLOWED-BUT-NO-CONSTRAINTS and SAME-AS-COMPILE-FILE
may break some existing programs that assume constants in code
processed by EVAL or COMPILE are always EQL to the corresponding
objects in the source code.  Proposal SAME-AS-COMPILE-FILE may also
break existing programs that depend on referencing "undumpable"
constants in code processed by EVAL or COMPILE.  In both cases,
however, the behavior is already nonportable.  Both proposals would
permit implementations in which these programs now work to continue to
provide their existing behavior.


Benefits:

The semantics of QUOTE are clarified.


Discussion:

This issue subsumes issue QUOTE-MAY-COPY, which caused a very lengthy
debate on the cl-compiler mailing list.

This issue relates to conformance requirements.  Accepting either of
proposals NO-COPYING or COPYING-ALLOWED-BUT-NO-CONSTRAINTS would mean
that not all conforming programs could be compiled with COMPILE-FILE.
Some people may find this disturbing, particularly since one of the
goals of Common Lisp has been to try to eliminate differences in
semantics between compiled and interpreted code.

Loosemore supports proposal QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE,
since it requires essentially no conversion cost for implementors and
does not break any user programs that are not already nonportable.

JonL White says:
  Since we have already passed the proposal that permits constants to 
  be "read-only" -- it is an error to modify them -- and have already 
  passed  the proposal that allows access to updateable structures -- 
  LOAD-TIME-EVAL -- then there is no excuse for being overly concerned
  with the storage address of quoted data.  People who have mistakenly 
  used structured constants as updatable data should convert over to 
  either LOAD-TIME-EVAL or DEFPARAMETER.

Kent Pitman says:
  The problem is that a lot of copying advocates have been going around
  trying to use "the need for copying" as leverage for restricting
  the set of things which I may quote. My view is that it is my write [sic]
  to quote whatever I want, and it's up to the person who thinks they
  can do something fun with copying to not get themselves in deeper than
  they can handle.

Jeff Dalton says: 
  I would agree [with Pitman's remarks] too.  My only quibble is that
  it's not just "the need for copying" that's used a lever.
  "Consistency with file compilation" is also being used as a lever.

UCL implements COMPILE by dumping and loading a temporary file using
the same mechanisms as COMPILE-FILE and LOAD.  Leigh Stoller (one of
the UCL compiler implementors) says that, even if this implementation
technique is disallowed by the outcome of this issue, they would
rather be nonconforming than change the implementation of COMPILE.  In
addition to the change being a lot of work, he says he thinks that
making COMPILE-FILE and COMPILE different would be "really dumb", and
that having different conformance requirements for compiled and
interpreted code would just encourage people to write programs that
can't be compiled correctly.
-------

∂23-Mar-89  1523	X3J13-mailer 	issue CONSTANT-CIRCULAR-COMPILATION, version 8
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89  15:23:21 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA12090; Thu, 23 Mar 89 13:49:30 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA12718; Thu, 23 Mar 89 13:49:27 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903232049.AA12718@defun.utah.edu>
Date: Thu, 23 Mar 89 13:49:25 MST
Subject: issue CONSTANT-CIRCULAR-COMPILATION, version 8
To: x3j13@sail.stanford.edu

Changes to this issue since version 7 (distributed last week) include:

- all references to EQ have been changed to EQL.
- error terminology has (hopefully) been fixed.
- added note about handling of uninterned symbols.


Forum:		Compiler
Issue:		CONSTANT-CIRCULAR-COMPILATION
References:	Issue CONSTANT-COLLAPSING
		Issue QUOTE-SEMANTICS
Category:	CLARIFICATION, ADDITION
Edit History:   V1, 07 Nov 1988, Sandra Loosemore
		V2, 14 Nov 1988, Cris Perdue
		V3, 12 Dec 1988, Sandra Loosemore (merge versions 1 and 2)
		V4, 03 Jan 1989, Sandra Loosemore (add PRESERVE-SHARING-ONLY)
		V5, 06 Jan 1989, Sandra Loosemore (minor wording changes)
		V6, 08 Feb 1989, Sandra Loosemore (replace FLAG with YES)
                V7, 11 Mar 1989, Sandra Loosemore (error terminology)
		V8, 18 Mar 1989, Sandra Loosemore (changes per Moon, Masinter)
Status:		Ready for release


Problem Description:

CLtL does not specify whether constants containing circular or
recursive references may be compiled.  It is also not clear whether
the compiler must preserve sharing of EQL substructures; that is, whether
subobjects that are EQL in the source code must remain EQL after being
compiled.

The proposals below apply to constants appearing in a file compiled by
COMPILE-FILE.  If proposal QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE
passes, then the same constraints would apply to all constants.  The
minimal scope over which sharing would be required to be detected is
over a single call to EVAL or COMPILE.

In the proposals that follow, "preserving EQLness" means that
subobjects that are EQL in the source code must remain EQL after being
compiled; that is, things don't get "less EQL" after compilation.
(Note that coalescing of constants implies that things may get "more
EQL".)


Proposal CONSTANT-CIRCULAR-COMPILATION:NO

State that conforming programs must not contain circular objects
appearing as constants to be compiled.  The consequences of compiling
a program containing such an object with COMPILE-FILE and/or LOADing
the output produced by COMPILE-FILE for such a program [and, if we
accept proposal QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE, compiling it
with COMPILE or evaluating it interpretively] are undefined.

State that the compiler is not required to preserve EQLness of
substructures.

  Rationale:

  This proposal would not require any existing implementation to change.

  Disallowing portable programs from containing circular constants
  allows compiled file loaders to use somewhat simpler implementation
  strategies (for example, to build constants in a strict bottom-up
  fashion).


Proposal CONSTANT-CIRCULAR-COMPILATION:PRESERVE-SHARING-ONLY

State that conforming programs must not contain circular objects
appearing as constants to be compiled.  The consequences of compiling
a program containing such an object with COMPILE-FILE and/or LOADing
the output produced by COMPILE-FILE for such a program [and, if we
accept proposal QUOTE-SEMANTICS:SAME-AS-COMPILE-FILE, compiling it
with COMPILE or evaluating it interpretively] are undefined.

State that the compiler is required to preserve EQLness of
substructures within a file compiled with COMPILE-FILE.

  Rationale:

  Disallowing portable programs from containing circular constants
  allows compiled file loaders to use somewhat simpler implementation
  strategies (for example, to build constants in a strict bottom-up
  fashion).

  Some programs (such as PCL) have come to depend on COMPILE-FILE 
  preserving the EQLness of uninterned symbols, and it is cleaner
  to require sharing to be preserved in general instead of making
  symbols be a special case.  Requiring sharing to be preserved still
  allows loaders to build constants bottom-up.


Proposal CONSTANT-CIRCULAR-COMPILATION:YES

State that objects containing circular references may legitimately
appear as constants to be compiled.  State that the compiler is
required to preserve EQLness of substructures within a file compiled
with COMPILE-FILE.

  Rationale:

  Users seem to expect this functionality, and some implementations 
  already provide it.


Current Practice:

A-Lisp preserves EQLness of substructures (since it makes an effort to
collapse isomorphic structures) but signals an error if an attempt is
made to compile a circular constant.  PSL and Utah Common Lisp both
get stuck in an infinite loop if an attempt is made to compile a
reentrant structure.  The TI Explorer compiler is able to reproduce
recursive lists and arrays, but currently hangs in a loop on a
circular list.  Neither the Explorer nor Symbolics Genera 7.x detects
EQLness of list CDRs.  Lucid handles circular constants correctly.
Franz uses a flag to control whether or not to attempt to detect
circular constants.  KCL handles circular structures, but only detects
sharing of top-level structure (it does not traverse constants to look
for shared substructure).


Cost to implementors:

We know of no implementation that would have to change under proposal
NO.  

For proposal YES, some implementations would require sweeping
changes; in some cases a completely different dumper/loader strategy
would have to be implemented.

The cost of proposal PRESERVE-SHARING-ONLY would fall somewhere in
between.


Cost to users:

The situation now is that programs which depend upon circularity or
sharing of substructure being preserved by the compiler are already
nonportable.  Proposal NO simply formalizes the status quo.  Proposal
YES would offer users functionality that is currently not portable.

Portable CommonLoops reportedly requires EQLness of uninterned symbols
to be preserved across a file, and would break under proposal NO.
According to Cris Perdue:

  I am told that support for PCL requires the kinds of guarantees about
  uninterned symbols [that say EQLness will be preserved].  Jim Kempf
  here at Sun tells me he believes that this is true.  John Foderaro
  said that Franz made their compiler give this behavior in order to
  support PCL.

  Jim Kempf says he believes that certain GENSYMs appear in multiple
  pieces of initialization code across a file in PCL, and the
  initialization code only works if symbols EQ at compile time map to
  symbols that are EQ at load time.


Benefits:

An area of ambiguity in the language is removed.


Discussion:

The issue of compiler speed is largely a red herring on this issue;
the overhead of detecting circularities is generally quite small.  The
main question is whether we should require some implementations to
completely redo their compiler/loader interface in order to support
circular constants.  

It has been argued that any "serious" implementation will support
circular constants anyway, because of customer demand.  However, since
there appears to be only one implementation (Lucid) that now
implements proposal YES in its full generality, perhaps the demand for
this feature is not really all that strong.

Earlier drafts of this writeup contained a proposal FLAG which would
have added a variable *COMPILE-CIRCLE*, similar to *PRINT-CIRCLE*.
However, there were unresolved problems about what would happen if the
value of this variable were altered within the file being compiled,
and it was generally agreed that this proposal didn't have any
particular advantages over proposal YES and just introduced
unnecessary hairiness.

Since it is usually fairly simple to detect circular constants,
Loosemore would support an amendment to proposals NO and
PRESERVE-SHARING-ONLY to change the word "undefined" to "unspecified",
adding:

  Implementations must either correctly handle the circular reference
  or signal an error.  

This is similar to the language which is already used in proposal
CONSTANT-COMPILABLE-TYPES:SPECIFY.

-------

∂23-Mar-89  1537	X3J13-mailer 	**DRAFT** Issue: PATHNAME-SUBDIRECTORY-LIST (Version 4) 
Received: from YUKON.SCRC.Symbolics.COM (SCRC-YUKON.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 89  15:36:24 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by YUKON.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 441574; Thu 23-Mar-89 16:01:03 EST
Date: Thu, 23 Mar 89 15:57 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** Issue: PATHNAME-SUBDIRECTORY-LIST (Version 4)
To: X3J13@SAIL.Stanford.EDU
Message-ID: <890323155755.4.KMP@BOBOLINK.SCRC.Symbolics.COM>

       >> PLEASE DO -NOT- REPLY TO THIS ISSUE <<<

Bring your comments to the meeting.

For those on CL-Cleanup, I modified this version only very slightly
to accomodate out-and-out typos. I have not made any new conceptual
strides on this pass.

All should see of CL-Cleanup discussion at end.
 -kmp

-----
Issue:          PATHNAME-SUBDIRECTORY-LIST
References:     Pathnames (pp410-413), MAKE-PATHNAME (p416),
		PATHNAME-DIRECTORY (p417)
Category:       CHANGE
Edit history:   18-Jun-87, Version 1 by Ghenis.pasa@Xerox.COM
	        05-Jul-88, Version 2 by Pitman (major revision)
		28-Dec-88, Version 3 by Pitman (merge discussion)
		23-Mar-89, Version 4 by Pitman ([hopefully] just fix typos)
Status:	        For Internal Discussion
Related-Issues: PATHNAME-COMPONENT-CASE

Problem Description:

  It is impossible to write portable code that can produce a pathname
  in a subdirectory of a hierarchical file system. This defeats much of
  the purpose of having an abstraction like pathname.

  According to CLtL, only a string is a portable filler of the directory
  slot, but in order to denote a subdirectory, the use of separators (such
  as dots, slashes, or backslashes) would be necessary. The very fact that
  such syntax varies from host to host means that although the
  representation might be "portable", the code using that representation 
  is not portable.

  This problem is even worse for programs running on machines on a network
  that can retrieve files from multiple hosts, each using a different OS
  and thus a different subdirectory delimiter.

  Related problems:

  - In some implementations "FOO.BAR" might denote the "BAR" subdirectory
    of "FOO" while in other implementations it might be a top-level 
    directory (because "." is not a subdirectory separator). To be safe,
    portable programs must avoid all potential separators.

  - Even in implementations where "." is the separator, "FOO.BAR" may be
    recognized by some to mean the "BAR" subdirectory of "FOO" and by others
    to mean `a seven letter directory with "." being a superquoted part of
    its name'.

  - In fact, CLtL does not even say for toplevel directories whether the
    directory delimiters are a part. eg, is "foo" or "/foo" the directory
    filler for a unix pathname "/foo/bar.lisp". Similarly, is "[FOO]" or
    "FOO" the directory filler for a VMS pathname "[FOO]ME.LSP"?

Proposal (PATHNAME-SUBDIRECTORY-LIST:NEW-REPRESENTATION)

  Allow a list to be a filler of a pathname. The car of the list may be either
  of the symbols :ABSOLUTE or :RELATIVE.

  If the car of the list is :RELATIVE, the rest of the list is the
  implementation-dependent result of PARSE-NAMESTRING for file systems which
  have relative pathnames. Unless some other proposal is submitted to clarify
  the behavior of relative pathnames in merging, etc. that behavior is left
  undefined.

  If the car of the list is :ABSOLUTE, the rest of the list is a list of 
  strings each naming a single level of directory structure. The strings
  should contain only the directory names themselves -- no separator
  characters.

  The spec (:ABSOLUTE) represents the root directory.

  Clarify that if a string is used as a filler of a directory field in a
  pathname, it should be the unadorned name of a toplevel directory.
  Specifying a string, str, is equivalent to specifying the list
  (:ABSOLUTE str).

  In place of a string, at any point in the list, keyword symbols may occur
  to deal with special file notations. The following symbols have standard
  meanings; they may not be meaningful for all operating systems, and are
  intended for use only on those operating systems where they have meaning:

   :WILD           - Wildcard match of one level of directory structure.
   :WILD-INFERIORS - Wildcard match of any number of directory levels.
   :UP             - Go upward in directory structure (syntactic).
   :BACK 	   - Go upward in directory structure (semantic).

  The difference between up and back is that if there is a directory
    (:ABSOLUTE "X" "Y" "Z")
  linked to 
    (:ABSOLUTE "A" "B" "C")
  and there also exist directories
    (:ABSOLUTE "A" "B" "Q")
    (:ABSOLUTE "X" "Y" "Q")
  then
    (:ABSOLUTE "X" "Y" "Z" :BACK "Q")
  designates
    (:ABSOLUTE "A" "B" "Q")
  while
    (:ABSOLUTE "X" "Y" "Z" :UP "Q")
  designates
    (:ABSOLUTE "X" "Y" "Q")

Test Case:

  (PATHNAME-DIRECTORY (PARSE-NAMESTRING "[FOO.BAR]BAZ.LSP")) ;on VMS
  => (:ABSOLUTE "FOO" "BAR")

  (PATHNAME-DIRECTORY (PARSE-NAMESTRING "/foo/bar/baz.lisp")) ;on Unix
  => (:ABSOLUTE "foo" "bar")
  or (:ABSOLUTE "FOO" "BAR")
  If PATHNAME-COMPONENT-CASE:CANONICALIZE passes, only the 2nd return value.

  (PATHNAME-DIRECTORY (PARSE-NAMESTRING ">foo>**>bar>baz.lisp")) ;on LispM
  => (:ABSOLUTE "FOO" :WILD-INFERIORS "BAR")

  (PATHNAME-DIRECTORY (PARSE-NAMESTRING ">foo>*>bar>baz.lisp")) ;on LispM
  => (:ABSOLUTE "FOO" :WILD "BAR")

Rationale:

  This would allow programs to usefully deal with hierarchical file systems,
  which are by far the most common file system type.

Current Practice:

  Symbolics Genera implements something very similar to this. The main
  differences are:
   - In Genera, there is no :ABSOLUTE keyword at the head of the list.
     This has been shown to cause some problems in dealing with root
     directories. Genera represents the root directory by a keyword
     symbol (rather than a list) because the list representation 
     was not adequately general.
   - Genera represents Unix ".." as :UP. Its treatment of :UP is compatible
     with this proposal, but Unix ".." is more properly represented by :BACK.

Cost to Implementors:

  In principle, nothing about the implementation needs to change except
  the treatment of the directory field by MAKE-PATHNAME and
  PATHNAME-DIRECTORY. The internal representation can otherwise be left
  as-is if necessary.

  For implementations that choose to rationalize this representation
  throughout their internals and any other implementation-specific
  accessors, the cost will be necessarily higher.

Cost to Users:

  None. This change is upward compatible.

Cost of Non-Adoption:

  Serious portability problems would continue to occur. Programmers would be
  driven to the use of implementation-specific facilities because the need
  for this is frequently impossible to ignore.

Benefits:

  The serious costs of non-adoption would be avoided.

Aesthetics:

  This representation of hierarchical pathnames is easy to use and quite
  general. Users will probably see this as an improvement in the aesthetics.

Discussion:

  This issue was raised a while back but no one was fond of the particular
  proposal that was submitted. This is an attempt to revive the issue.

  The original proposal, to add a :SUBDIRECTORIES field to a pathname, was
  discarded because it imposed an unnatural distinction between a toplevel
  directory and its subdirectories. Pitman's guess is the the idea was to
  try to make it a compatible change, but since most programmers will 
  probably want to change from implementation-specific primitives to portable
  ones anyway, that's probably not such a big deal. Also, there might have
  been some programs which thought the change was compatible and ended up
  ignoring important information (the :SUBDIRECTORIES field). Pitman thought
  it would be better if people just accepted the cost of an incompatible
  change in order to get something really pretty as a result.

  This issue used to address the issue of relative pathnames (pathnames
  relative to some default which is separately maintained). Pitman removed
  this issue for now in order to simplify things. He feels the issue should
  be resubmitted under separate cover so that it can be discussed separately.

------
Summary of discussion on CL-Cleanup:

 Moon wondered if functions like Symbolics' DIRECTORY-PATHNAME-AS-FILE
  and PATHNAME-AS-DIRECTORY should be included either here or in
  another issue. (The conversion between the name of a directory
  and the directory component of a file inferior to that directory is
  system-dependent, for example TOPS-20 appends a type field and Unix
  does not.  Also in some systems the root directory has a name and
  in others it doesn't.  Of course these functions signal an error in
  non-hierarchical file systems.

 Moon doesn't think :UP and :BACK are meaningful anywhere except 
  immediately after :RELATIVE, although he concedes Unix disagrees
  with him. He suggests that if they were only allowed immediately
  after :RELATIVE, you wouldn't need two of them.  He also doesn't
  think that MERGE-PATHNAMES should ever look at what files/directories
  actually exist in the file system, which makes me opposed to the
  existence of the one that you have called syntactic.  He asks ``is
  this really something we need, or will TRUENAME do the job?''

 JLM replies (to Moon's query) that if you're trying to create a
  filename to be used for output, it might not exist yet
  (hence TRUENAME would signal an error), but there might
  be various funny links in its directory path you would like to
  traverse.  Presumably you could use PROBE-FILE on some part of the
  name (perhaps recursively down through the super-directories), then
  merge in the remaining part, but that seems enough error-prone to be
  worth hiding. 

 Aaron Larson has a competing or related proposal he wants to present
  on this issue. I didn't attempt to summarize it here because it was
  enough different from this discussion to raise presentational 
  confusion. My attempt here was mainly to get these thoughts on the
  table -- not to preempt what he has to say.  Hopefully he'll still
  present his views separately.

∂23-Mar-89  1552	X3J13-mailer 	Issue: PATHNAME-COMPONENT-VALUE (version 1)   
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 23 Mar 89  15:51:29 PST
Received: from pitney-bowes ([192.9.200.50]) by heavens-gate.lucid.com id AA03604g; Thu, 23 Mar 89 13:25:02 PST
Received: by pitney-bowes id AA26521g; Thu, 23 Mar 89 13:23:24 PST
Date: Thu, 23 Mar 89 13:23:24 PST
From: Jim McDonald <jlm@lucid.com>
Message-Id: <8903232123.AA26521@pitney-bowes>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
Cc: X3J13@SAIL.STANFORD.EDU
In-Reply-To: David A. Moon's message of Tue, 21 Mar 89 17:52 EST <19890321225242.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: Issue: PATHNAME-COMPONENT-VALUE (version 1)

Food for thought:

An interesting alternative that was just suggested to me would split
the type PATHNAME into something like PATHNAME and PATHNAME-TEMPLATE.
OPEN, TRUENAME, and friends would accept only PATHNAME arguments,
and DIRECTORY would accept only PATHNAME-TEMPLATE arguments.
(DIRECTORY would return a list of PATHNAME's.)

This would perhaps enhance our ability to stabilize the syntax and
semantics of PATHNAME much more rigidly, and leave open room for
experimentation with PATHNAME-TEMPLATE, where there seems to be more
need for it.  

The basic idea is that a pathname would specify at most one file (it
could be bogus), whereas PATHNAME-TEMPLATE would specify a set of
files. 

  jlm


∂23-Mar-89  1527	X3J13-mailer 	issue DEFINE-OPTIMIZER, version 6   
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89  15:26:04 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA13550; Thu, 23 Mar 89 14:18:32 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA12741; Thu, 23 Mar 89 14:18:28 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903232118.AA12741@defun.utah.edu>
Date: Thu, 23 Mar 89 14:18:27 MST
Subject: issue DEFINE-OPTIMIZER, version 6
To: x3j13@sail.stanford.edu

There have been a number of small changes made to this writeup.

- The description of DEFINE-OPTIMIZER now says that the optimizer should
  return only one value.
- The relationship to INLINE/NOTINLINE declarations has been clarified.
- There have been some minor clarifications to wording.
- The discussion section has been expanded.

Forum:	      Compiler
Issue:        DEFINE-OPTIMIZER
References:   Issue SYNTACTIC-ENVIRONMENT-ACCESS
Category:     ADDITION
Edit history: 28-Sep-88, Version 1 by Pitman
	      10-Mar-89, Version 2 by Pitman (clarifications, new example),
	      10-Mar-89, Version 3 by Pitman & Loosemore
	      11-Mar-89, Version 4 by Pitman
	      13-Mar-89, Version 5 by Loosemore (discussion)
	      22-Mar-89, Version 6 by Loosemore (more discussion)
Status:	      Ready for release

Problem Description:

  Often a general functional interface could be bypassed given explicit
  knowledge of the arguments passed. This may happen when the arguments
  are constant (or otherwise inferrable), an argument type is known (eg,
  due to use of THE or DECLARE), or when some particular pattern of
  optional, rest or keyword arguments is apparent.

  Most implementations provide internally for optimization of generalized
  function call interfaces to more specialized ones, but such an
  optimization facility is not provided to Common Lisp users.

  The absence of this facility in a portable fashion means that some
  CL programs run slower than they need to in some implementations, or
  else that some operators that should be implemented as functions end
  up getting implemented as macros to assure needed efficiency.

Proposal (DEFINE-OPTIMIZER:NEW-FACILITY):

  Introduce a facility for declaring compiler optimizations.

  DEFINE-OPTIMIZER name arglist {declaration}* {form}*		[Macro]

   Defines a compiler optimizer for a function named NAME. The ARGLIST,
   DECLARATIONS, and FORMS are treated exactly like the arglist, 
   declarations, and forms in a DEFMACRO. (The arglist may include
   &ENVIRONMENT and &WHOLE.)

   The argument NAME must name a function which has been previously
   defined. The effects of defining an optimizer for a locally or
   globally defined macro, a locally defined function, or a special 
   form are undefined.

   When the optimizer is invoked, the forms are executed in the context
   of bindings specified by the arglist as an implicit PROGN.  The 
   optimizer should return a form which is preferable to evaluate instead
   of the indicated call, or NIL to decline to optimize.  If an optimizer
   wishes to optimize into a form whose result is NIL, it should return
   (QUOTE NIL).  The resulting form should be careful to preserve the
   semantics (including order-of-evaluation) of the original function
   call.

   If a call to DEFINE-OPTIMIZER appears at top-level in a file
   being processed by the file compiler, it also makes the optimizer 
   known at compile-time (similar to the way DEFMACRO makes a macro 
   definition known to the compiler).

  OPTIMIZE-EXPRESSION-1 form env				[Function]

   Similar to MACROEXPAND-1. Invokes the optimizers for the top level of
   FORM, but does not iterate on the result. Returns two values:
   RESULT and CHANGED-P. 

   Note: If an optimizer declines to optimize, 
    OPTIMIZE-EXPRESSION-1 hides the fact by returning FORM,NIL
    rather than NIL,NIL.

  OPTIMIZE-EXPRESSION form env					[Function]

   Iterates calling OPTIMIZE-EXPRESSION-1 until the CHANGED-P result
   is NIL.  Two values are returned:  RESULT and CHANGED-P.

  An implementation must save optimizer definitions created by
  DEFINE-OPTIMIZER in case OPTIMIZE-EXPRESSION is attempted, but is
  not actually required to call OPTIMIZE-EXPRESSION itself. Interpreters,
  for example, may choose to just call the unoptimized form.

  Special forms such as FLET and MACROLET that create local functional
  definitions shadow not only functions and their SETF methods,
  but also their optimizers.  No portable facility is provided for creating
  locally defined optimizers.

  The effect of defining optimizations for functions in the LISP package
  is not defined. (In some implementations, this would clobber or conflict
  with existing advice that may be of higher quality.)

  The editor is advised that a non-binding style note such as the
  following would also be appropriate:

    In general, it is poor style for a programmer to define optimizers for
    functions that he does not maintain. This is because the correct
    implementation of an optimizer for a function usually depends on an
    understanding of the internals of that function. As such, a function 
    definition and any optimizers should be maintained as a unit so that
    they can changes in either can be synchronized as appropriate with the
    other.

  If a function that has an optimizer function is declared INLINE,
  the optimizer has precedence.  If a function that has an optimizer
  function is declared NOTINLINE, the application of the optimizer
  function by OPTIMIZE-EXPRESSION and OPTIMIZE-EXPRESSION-1 is
  inhibited.

Example:

  ;; These examples are taken literally from the Macsyma sources,
  ;; modified only to change DEFOPT to DEFINE-OPTIMIZER. The comments
  ;; were specially written for the X3J13 audience.

  ;; M+ is adds a Macsyma expression to another Macsyma expression.
  ;; The Macsyma internal representation for the sum of X and Y is
  ;; ((MPLUS) X Y). A all the real work is done by SIMPLIFY, which
  ;; reduces the expression as needed necessary. However, SIMPLIFY
  ;; is very complicated, and considerable speed can be gained by
  ;; entering it at specific known places.

  (DEFUN M+ (&REST TERMS)
    (PROTECT-&REST-VARIABLE TERMS)
    (SIMPLIFY `((MPLUS) ,@TERMS)))

  (DEFINE-OPTIMIZER M+ (&REST TERMS)
    (COND ((= (LENGTH TERMS) 2) `(ADD2* ,@TERMS))
	  (T `(ADDN (LIST ,@TERMS) NIL))))

  ;; M- negates a Macsyma expression, or substracts two Macsyma
  ;; expressions. Once you figure out which of the two operations is
  ;; to be done, the problem is similar to that of M+ above. However,
  ;; often the decision can be made at compile time. In this case,
  ;; INLINE functions would have worked ok, except that not all
  ;; implementations do inlining, and even those that do may fail to
  ;; recognize that EXP2 being NIL means that a test can be eliminated
  ;; or dead code can be eliminated. Using optimizers is far more
  ;; likely to be useful in practice.

  (DEFUN M- (EXP1 &OPTIONAL (EXP2 NIL EXP2P))
    (IF (NOT EXP2P)
	(M--INTERNAL-NEGATE EXP1)
	(M--INTERNAL-SUBTRACT EXP1 EXP2)))

  (DEFINE-OPTIMIZER M- (EXP1 &OPTIONAL (EXP2 NIL EXP2P))
    (IF (NOT EXP2P)
	`(M--INTERNAL-NEGATE ,EXP1)
	`(M--INTERNAL-SUBTRACT ,EXP1 ,EXP2)))

Rationale:

  Many large portable applications expect such a facility on an 
  implementation-specific basis. Others would use one if available.

  Even if implementations don't use the provided optimizers primitively,
  user macros and code-walkers can invoke them, so the facility wouldn't
  be completely useless even in those implementations.

  The rationale for giving optimizers precedence over INLINE declarations
  is that the optimizer can look for special patterns in the arguments,
  and defer to the inline if it doesn't find them.


Current Practice:

  Symbolics Genera provides an optimizer facility which is more elaborate
  but not fundamentally incompatible with this facility.

  Many (if not most) serious implementations provide a similar facility.
  For example, Lucid provides "compiler macros" which serve the same
  purpose.

Cost to Implementors:

  Since the implementation is not required to use this facility, the
  cost of providing the proposed support is very small.

Cost to Users:

  None. This change is upward compatible.

Cost of Non-Adoption:

  Portable code would be slower than necessary in some situations.

Benefits:

  Some existing non-portable code could become portable.

Aesthetics:

  Providing a separate optimizer definition from a main function definition
  makes a possibility that the optimizer and main function could drift out
  of synch. However, most places where this gets used in the first place
  are places where speed is of paramount importance and the programmer is
  willing to invest effort in maintaining things correctly and to accept the
  risk of lossage if s/he fails.

  This is a fairly clean and simple extension which adds significant
  power to the compiler.

Discussion:

  Pitman strongly supports this proposal, the design of which is modeled
  directly after that which has been used in Macsyma for many years.

  Information about argument type can come from two different sources:
  THE and declarations (via PROCLAIM or DECLARE). The former information
  is portably accessible, the latter is not.  While a separate proposal
  (SYNTACTIC-ENVIRONMENT-ACCESS) for allowing program access to type
  declarations would be make this facility more useful, it is still
  quite useful without it, as the examples from Macsyma illustrate.

  Some implementations provide a way to provide more than one optimizer
  for the same function. A multiple optimizer facility can be written
  in terms of this simpler facility and vice versa, so the simpler of
  the two facilities is proposed here.

  Some people have suggested that they would like to see a pattern
  matching facility integrated into this facility. The design of a
  facility that would satisfy everyone would take a lot of time and
  effort. At this point, there is no chance that the design of such a
  facility would occur in time for acceptance into the standard.
  The choice is this or nothing. Pitman thinks the language is much
  better off with some form of optimization support than none.

  David Moon says:
    I'm not a fan of documentation strings, but shouldn't DEFINE-OPTIMIZER
    allow them?  Was their omission accidental or intentional?

  It was probably accidental, but it's hard to say what should be done
  with them if they are supported.  Presumably the function already
  would have its own FUNCTION documentation.  Should the DOCUMENTATION
  function be extended to recognize OPTIMIZER as a doc-type symbol?

  Loosemore says:
    Although I don't really think this is an essential feature to include
    in the standard, I don't have any strong objection to adding it.  If
    people think it's a good idea to provide a standard interface for this
    kind of thing, this is a good proposal for doing it -- it's fairly
    simple, doesn't introduce any radically new ideas, and is general
    enough to allow alternate interfaces (such as the pattern matcher) to
    be layered on top of it.

  From Barry Margolin:
    While I like the proposal in general, I don't think it's appropriate to
    add this to the language at this time.  If most Lisp vendors are in
    favor of it, though, my objection is pretty weak.  But there's still the
    editorial issue of adding it to the standard.  I don't really think it's
    worth it for the first version of the standard.

    Also, I don't see a whole lot of value in portable optimizers.  Yes, the
    Macsyma example is a good one, but the real value of optimizers comes
    when they translate into calls to extra fast, internal functions.
    Portable optimizers can't do this, and non-portable optimizers don't
    need to be defined using a portable mechanism.

  From Kent Pitman:
    I believe this claim is unsubstantiated and unsubstantiable. In many
    implementations, internal functions have no special property that user
    programs do not.  In some cases, that makes the optimizers that much
    more important since most internal functions run a constant factor 
    faster, but do not have any algorithmic leverage over user programs.
    Optimizers are potentially able to do much better than built-in 
    optimizations because they can use domain-specific information that
    is beyond the power of even the proverbial SCC (Sufficiently Clever
    Compiler).
    
    Optimizers have been around for a -long- time. They are not new
    technology. If we cannot adopt at least this much this time, I see
    no reason why for CL 2000 we won't have the exact same arguments
    raised and we -still- won't get anything.  On the other hand, if we
    adopt them now we get years of field testing, and next time there
    will be a lot of users with suggestions about how to improve them.
    Some progress must be made incrementally -- but no progress is made
    if the increment is zero.
    
    The risks are very low. This proposal already says the optimizer
    function has to be semantics-preserving, and that it might never be
    called. It's hard to see how that can go wrong.
    
    For so little cost and so much potential gain, I think it is worth any
    associated risk.

  From Robert Krajewski:
    I think a portable optimizer definer is a fine idea.  It's especially
    useful for authors of Common Lisp-embedded subsystems that offer safe
    access to their data structures in a development environment, but who
    also wish to produce fast code for delivery.  In such cases, an
    optimizer should only run when unsafe code is desired.

  From Richard Gabriel:
    I oppose this proposal. First, optimization is rarely something that
    can be done portably. Using a name like define-optimizer gives the
    impression that something will be done more optimally, and maybe it
    won't.
    
    Second, it appears that this functionality is isomorphic to macros,
    except possibly macros that are only in effect during compilation.
    
    Third, it seems to solve a problem that is addressed by all the various
    abstraction mechanisms around already.
    
    Fourth, it is part of a trend I will call ``featherbedding'', which I
    will use in my messages to refer to adding comfortable features to
    Common Lisp that are redundant or not strictly necessary.

  From Dick Waters:
    I would like to say that I think that compiler optimizers are an
    extremely good idea---right up there with the best of the ideas ever
    presented to the committee.
    
    I really hate having to make things macros for trivial reasons,
    because this blocks you from funcalling them and using them as
    arguments to MAPCAR REDUCE etc.  If this mechanism were in Common Lisp
    I would use it all the time.  I bet it would cover a significant chunk
    of what I use macros for.
    
    To be more specific, there are a number of places where such compiler
    optimizers would be of HUGE benefit in my portable implementation of
    SERIES.  In particular, they would be an appropriate framework in
    which to state the whole thing.  Now, since I have to do it all with
    macros, a number of things that should, by every right, be functions
    have to be macros instead.  This in fact makes it impossible to make an
    implementation of what I really want.
-------

∂23-Mar-89  1552	X3J13-mailer 	Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 23 Mar 89  15:51:46 PST
Received: from challenger ([192.9.200.17]) by heavens-gate.lucid.com id AA03601g; Thu, 23 Mar 89 13:23:09 PST
Received: by challenger id AA24966g; Thu, 23 Mar 89 13:18:25 PST
Date: Thu, 23 Mar 89 13:18:25 PST
From: Richard P. Gabriel <rpg@lucid.com>
Message-Id: <8903232118.AA24966@challenger>
To: x3j13@sail.stanford.edu
Subject: Issue: ADJUST-ARRAY-NOT-ADJUSTABLE (Version 9)


Moon raises an important point about conceptual versus
representational types. It always struck me that simple arrays as
defined in Version 9 were somewhat like each of these two things.

Moon also points out the FIXNUM/SIMPLE-ARRAY analogy. Let's look more
at this analogy:

Suppose I have some piece of code like this:

(defun f (x) ...)

and I want to know whether to put in a FIXNUM declaration for a
different target CL about which I know everything. In order to do that
I have to look at the calls to F to see whether they all produce
FIXNUMs for the target CL. Usually I look no further, but in general I
must look all the way back from each call to F to the origin of the
argument that is passed to F. The reason I usually have to look no
further than the call is that this is typically where the number is
created.

Now suppose the piece of code really takes an array, and I want to put
in a SIMPLE-ARRAY declaration so that I can get fast array access.  I
cannot look only at the calls to F, nor can I look at the creation of
the arrays that get passed to F, but I have to look at all operations
on F to see whether any of them is an ADJUST-ARRAY.  That is, I cannot
simply look all the way back from each invocation of F to the creation
of the argument that is passed, but I also have to look all the way
forward to the termination of the program.

In the FIXNUM example, this is as if I had to look at all the
operations on the numbers being fed to F (either before or *after* F
in execution order) to see whether some particular operation was
applied to an argument to F.  That is, I cannot look at dataflow up to
the call to F to determine whether it is an simple array, I have to
look at the entire life history of the objects passed to F.

This leads to what I think is an interesting point. Some theorists
define a type as being the set of objects that can be passed to a
particular set of functions or operations. That is, a number is
something you can add, subtract, multiply, and divide, for example.
Some describe this by saying that a type is the set of objects that
respond to the same protocol.

In all implementations, FIXNUMs and BIGNUMs can be operated on by the
same set of functions and operations. Thus, FIXNUMs and BIGNUMs are
merely representational variants on the same type (namely, INTEGER).

In all implementations, ARRAY can be operated on by AREF, SETF of
AREF, and ADJUST-ARRAY (and some others). 

In some implementations, SIMPLE-ARRAY can be operated on by AREF, SETF
of AREF (and some others), but not by ADJUST-ARRAY. Thus, in some
implementations SIMPLE-ARRAY responds to a different protocol and so
it is a conceptual type, while in implementations it is a
representational type.

This is, I think, the source of my uneasiness about the whole issue:
Version 9 legitimizes SIMPLE-ARRAY being a representational type in
some Common Lisps and a conceptual type in others. Only people who are
porting will notice the difference.

				-rpg-

∂23-Mar-89  1526	X3J13-mailer 	issue CONSTANT-COMPILABLE-TYPES, version 9    
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89  15:24:39 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA11960; Thu, 23 Mar 89 13:45:42 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA12712; Thu, 23 Mar 89 13:45:38 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903232045.AA12712@defun.utah.edu>
Date: Thu, 23 Mar 89 13:45:37 MST
Subject: issue CONSTANT-COMPILABLE-TYPES, version 9
To: x3j13@sail.stanford.edu

There have been extensive revisions made to this writeup since the
previous version was distributed last week.  Most of the changes,
however, have been of an editorial nature.  There are two substantive
changes to watch out for:

- The special treatment for uninterned symbols (requiring EQLness of
  symbols within a single file to be preserved) has been removed from
  this issue, since that more properly falls into the domain of issue
  CONSTANT-CIRCULAR-COMPILATION.

- The problems of what to do with constant functions have been deferred
  to a new issue, CONSTANT-FUNCTION-COMPILATION.


Forum:		Compiler
Issue:		CONSTANT-COMPILABLE-TYPES
References:	CLtL pp. 56, 77-80, 324
		Issue CONSTANT-MODIFICATION
		Issue CONSTANT-CIRCULAR-COMPILATION
		Issue CONSTANT-COLLAPSING
		Issue QUOTE-SEMANTICS
		Issue LOAD-OBJECTS
		Issue CONSTANT-FUNCTION-COMPILATION
Category:	CLARIFICATION, ADDITION
Edit history:	11/07/88, V1 by Cris Perdue
		11/14/88, V2 by Cris Perdue
		11/22/88, V3 by Cris Perdue
		12/20/88, V4 by Cris Perdue
		01/06/89, V5 by Sandra Loosemore (minor editorial
			clarifications, expand discussion)
		03/05/89, V6 by Cris Perdue (more response to comments,
			especially from Moon and and from Loosemore)
                03/05/89, V7 by Loosemore (more editorial tweaks)
		03/13/89, V8 by Loosemore (discussion)
		03/22/89, V9 by Loosemore (restructure)
Status:		Ready for release

Problem description:

CLtL does not specify what objects can be in compiled constants and it
does not say what relationship there is to be between the constant
passed to the compiler and the one that is established by compiling
and then loading its file.  Relevant remarks in CLtL concerning file
compilation and the definition of QUOTE suggest that the compiler
handles constants in ways that are not actually possible.


Introduction to the proposal:

The proposal CONSTANT-COMPILABLE-TYPES:SPECIFY attempts to spell out
what types can appear in compiled constants, and what it means when
they appear.

The key is a definition of an equivalence relationship between Lisp
objects, "similarity as constants".  Code passed through the file
compiler and then loaded must behave as though quoted constants in it
are "similar" to quoted constants in the corresponding source code.

Issue CONSTANT-COLLAPSING addresses the issue of whether, for two
objects that are not EQL in the source code (but which are similar as
constants), the corresponding objects in the compiled code may be
EQL.

Issue CONSTANT-CIRCULAR-COMPILATION addresses the issue of whether,
for two objects that are EQL in the source code, the corresponding
objects in the compiled code must also be EQL.

Comments within the text of the proposal are enclosed in double angle
brackets, <<like this>>.


Proposal:  CONSTANT-COMPILABLE-TYPES:SPECIFY

An object may be used as a quoted constant processed by COMPILE-FILE
if the compiler can guarantee that the resulting constant established
by loading the compiled file is "similar as a constant" to the
original.

Some types of objects, such as streams, are not supported in constants
processed by the file compiler.  Such objects may not portably appear
as constants in code processed with COMPILE-FILE.  Conforming
implementations are required to handle such objects either by having
the compiler and/or loader reconstruct an equivalent copy of the
object in some implementation-specific manner; or by having the
compiler signal an error.

Of the types supported in constants, some are treated as aggregate
objects.  For these types, being similar as constants is defined
recursively.  We say that an object of these types has certain "basic
attributes", and to be similar as a constant to another object, the
values of the corresponding attributes of the two objects must also be
similar as constants.

This kind of definition has problems with any circular or "infinitely
recursive" object such as a list that is an element of itself.  We use
the idea of depth-limited comparison, and say that two objects are
similar as constants if they are similar at all finite levels.  This
idea is implicit in the definitions below, and applies in all the
places where attributes of two objects are required to be similar as
constants.

The following terms are used throughout this proposal:

  The term "constant" refers to a quoted or self-evaluating constant,
  not a named (defconstant) constant.

  The term "source code" is used to refer to the objects constructed
  when COMPILE-FILE calls READ, and additional objects constructed by
  macroexpansion during COMPILE-FILE.

  The term "compiled code" is used to refer to objects constructed by 
  LOAD.

Two objects are defined to be "similar as a constant" if and only if
they are both of one of the types listed below and satisfy the
additional requirements listed for that type.

Number

  Two numbers are similar as constants if they are of the same type
  and represent the same mathematical value.
  
Character

  Two characters are similar as constants if they both represent
  the same character.

  <<Note that this definition has to depend on the results of the
  Character Set proposals.  The intent is that this be compatible with
  how EQL is defined on characters.>>

Symbol

  Issue COMPILE-FILE-SYMBOL-HANDLING defines how the file compiler
  and loader handle interned symbols.

  An uninterned symbol in the source code is similar as a constant
  to an uninterned symbol in the compiled code if their print names
  are similar as constants.

Package

  A package in the source code is similar as a constant to a package in
  the compiled code if their names are similar as constants.  Note that
  the loader finds the corresponding package object as if by calling
  FIND-PACKAGE with the package name as an argument.  An error is
  signalled if no package of that name exists at load time.

Random-state

  Let us say that two random-states are functionally equivalent if 
  applying RANDOM to them repeatedly always produces the same 
  pseudo-random numbers in the same order.  
  
  Two random-states are similar as constants if and only if copies of
  them made via MAKE-RANDOM-STATE are functionally equivalent.

  Note that a constant random-state object cannot be used as the "state"
  argument to the function RANDOM (because RANDOM side-effects this
  data structure).

Cons

  Two conses are similar as constants if the values of their respective
  CAR and CDR attributes are similar as constants.

Array

  Two arrays are similar as constants if the corresponding values each
  of the following attributes are similar as constants:

  For 1-dimensional arrays:
  LENGTH, ARRAY-ELEMENT-TYPE, and ELT for all valid indices.

  For arrays of other dimensions:
  ARRAY-DIMENSIONS, ARRAY-ELEMENT-TYPE, AREF for all valid indices.

  In addition, if the array in the source code is a SIMPLE-ARRAY, then
  the corresponding array in the compiled code must also be a
  SIMPLE-ARRAY.  If the array in the source code is displaced, has a
  fill pointer, or is adjustable, the corresponding array in the
  compiled code is permitted to lack any or all of these qualities.

Hash Table   

  Two hash tables are similar as constants if they meet the following
  three requirements:

  (1) They both have the same test (e.g., they are both EQL hash tables).

  (2) There is a unique one-to-one correspondence between the keys of
      the two tables, such that the corresponding keys are similar as
      constants.

  (3) For all keys, the values associated with two corresponding keys
      are similar as constants.

  If there is more than one possible one-to-one correspondence between
  the keys of the two tables, the results are unspecified.  A conforming
  program cannot use such a table as a constant.

Pathname

  Two pathnames are similar as constants if all corresponding pathname
  components are similar as constants.

Stream, Readtable, Generic-function, Method

  Objects of these types are not supported in compiled constants.

Function

  Issue CONSTANT-FUNCTION-COMPILATION specifies how the compiler and
  loader handle constant functions.


Structure, Standard-object

  <<There is a cl-cleanup issue, LOAD-OBJECTS, pending which proposes
  a mechanism for dealing with objects.>>


Rationale:

For the benefit of users, this proposal tries to define a fairly large
set of types that all Common Lisp implementations are to handle.  It
also attempts to leave room for implementations to differ.  Some
implementations have made opposing choices because the language
doesn't specify one over the other.  Some implementations already
handle constants that this proposal defines as not valid in Common
Lisp programs, and that is useful to users of those systems.
Different implementors have different amounts of resources to apply to
their system, and implementations differ in their whole approach in
some cases.

This proposal appears to reflect user demand and appears not to exceed
the capabilities of most implementations of the language.


Current practice:

>From Gail Zacharias (Nov 14): "Coral pretty much implements this
proposal (I think we currently coalesce hash table keys, but that's
just a bug that will be fixed).  We also fasdump packages (using the
package name) and compiled functions (but not foreign functions).  For
symbols, we dump the name, and if (roughly speaking) the symbol would
get printed with a package prefix, we also dump the package name and
load the symbol into that package (otherwise it gets loaded into the
current load-time package)."

>From David Gray (Nov 9): "The Explorer can compile constant functions,
read tables, and hash tables; an error is signalled for a stream.  A
package object used to break the compiler but in release 5 it has been
fixed to generate instructions to call FIND-PACKAGE on the package
name at load time."  (Nov 15): [The Explorer does not guarantee
retention of displaced-to and displaced-index-offset attributes.]
"The Explorer also does not currently support dumping closures (either
compiled or evaluated), although non-closure compiled functions can be
dumped."

>From David Moon (Jan 24): "Symbolics Genera current practice: aside
from some current bugs we have with circular structures of certain
types and with preserving the identity of CONSes under EQ, this is
more or less consistent with our current practice, if you made the
changes implied by my earlier comments.  We preserve the :displaced-to
and :fill-pointer array attributes.  I doubt that we do what the
proposal says for hash-tables, readtables, and random-states.  We
support dumping compiled and interpreted functions, but not closures,
which in effect means we don't support dumping functions."

>From Sandra Loosemore (Mar 3): "UCL currently can handle only
constants that are of type number, character, symbol, cons,
simple-vector, or string (which it turns into simple-string).  It
signals an error if an attempt is made to compile any other kind of
object as a constant."


Adoption cost:

Not known.  Probably moderate or low -- for most implementations.  The
cost would be to implementors rather than users since this part of the
language is currently underspecified.  The author believes the cost
will be reasonable for KCL, an implementation where there is some
concern about this issue.

This proposal is close to compatible with the Franz, Lucid, Coral,
Texas Instruments, and Symbolics implementations.  It is probably
compatible or nearly compatible with other "Lisp Machine"
implementations.


Benefits:

Users would be able to use aggregate objects in constants with
confidence about the behavior of their code.


Conversion cost:

Where this proposal *requires* different behavior than an existing
implementation, there is a conversion cost for users of that
implementation.  It appears that this cost will be small, less than
the cost of leaving things unspecified.


Esthetics:

Since there is no adequate definition at present, a fuller definition
would be more esthetic.


Discussion:

This proposal does leave some user-visible attributes of objects
unspecified across the compile-and-load process, except that they must
be consistent with the attributes that must be retained.  This
situation is a compromise between the desire for full specification on
the one hand, and on the other hand the desire to leave freedom for
different implementations to remain different and to support some
optimizations such as compacting hash tables and "simplifying" arrays.

Proposals will be entertained for tighter specification of datatypes
such as arrays.

The definition of similarity for random-states supports the
possibility of random states that are immutable because of being in
compiled constants.

Readtables need not be supported by an implementation.  If a readtable
contains only symbols to represent functions, here is Cris Perdue's
suggested spec for similarity of readtables:

  Character syntax type for each character in the table;
  function for each readmacro character, mappings for
  dispatch macros; whether terminating or nonterminating
  for each readmacro.

Interest has been expressed by a number of people including users, in
support for user-definable "dumping" of CLOS objects and structure
instances.  The cleanup issue LOAD-OBJECTS deals with this.

This subsumes the issue CONSTANT-ARRAY-ATTRIBUTES.

Earlier versions of this proposal specified an additional constraint
on uninterned symbols, requiring EQLness to be preserved across the
entire file.  However, this special case was removed because it was
thought that including it in this issue made its presentation
unnecessarily complicated, since preservation of EQLness is really a
separate issue (CONSTANT-CIRCULAR-COMPILATION).  A consequence of the
decision to remove the special casing for uninterned symbols is that,
unless we accept one of the two CONSTANT-CIRCULAR-COMPILATION
proposals that requires EQLness of constants to be preserved, the
behavior for uninterned symbols will be rather strange.  PCL will
reportedly break if uninterned symbols that are EQL in the source code
do not remain EQL in the compiled code.
-------

∂23-Mar-89  1526	X3J13-mailer 	issue SYNTACTIC-ENVIRONMENT-ACCESS, version 6 
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89  15:25:09 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA17795; Thu, 23 Mar 89 16:24:48 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA12801; Thu, 23 Mar 89 16:24:44 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903232324.AA12801@defun.utah.edu>
Date: Thu, 23 Mar 89 16:24:42 MST
Subject: issue SYNTACTIC-ENVIRONMENT-ACCESS, version 6
To: x3j13@sail.stanford.edu

There have been a number of changes to the writeup on this issue since
version 4, which was distributed last week.  (Version 5 was circulated
only to cl-compiler.)  There are some new functions proposed, and
others have been combined.  There seemed to be general agreement that
only the material in proposal SMALL was anywhere near ready to be
standardized at this time, so proposals MEDIUM and LARGE have gone
away. 

We have still been having problems deciding upon the exact form of
accessors for declarations.  If what's specified in this version is
not acceptable, we may have to scrap that part of the proposal for
now.

Forum:		Compiler
Issue:          SYNTACTIC-ENVIRONMENT-ACCESS
References:     CLtL Chapter 8: Macros,
                Issue MACRO-FUNCTION-ENVIRONMENT
                Issue GET-SETF-METHOD-ENVIRONMENT
                Issue COMPILE-FILE-ENVIRONMENT
		Issue FUNCTION-NAME
		Issue PROCLAIM-LEXICAL
		Issue MACRO-ENVIRONMENT-EXTENT
		Issue DESTRUCTURING-BIND
		Issue DEFINING-MACROS-NON-TOP-LEVEL
Category:       ADDITION
Edit history:   Version 1, 2-Oct-88, Eric Benson
                Version 2, 17-Feb-89, Kim A. Barrett
		Version 3, 9-Mar-89, Kim A. Barrett (respond to comments)
		Version 4, 12-Mar-89, Sandra Loosemore (more revisions)
		Version 5, 20-Mar-89, Sandra Loosemore (only proposal SMALL)
		Version 6, 23-Mar-89, Sandra Loosemore (more revisions)
Status:         **DRAFT**


Problem description:

 When macro forms are expanded, the expansion function is called with
 two arguments: the form to be expanded, and the environment in which
 the form was found.  The environment argument is of limited utility.
 The only use sanctioned currently is as an argument to MACROEXPAND or
 MACROEXPAND-1 or passed directly as an argument to another macro
 expansion function.  Recent cleanup issues propose to allow it as an
 argument to MACRO-FUNCTION and to GET-SETF-METHOD.

 It is very difficult to write a code walker that can correctly handle
 local macro and function definitions, due to insufficient access to
 the information contained in environments and the inability to
 augment environments with local definitions.


Proposal (SYNTACTIC-ENVIRONMENT-ACCESS:SMALL):

 The following functions provide information about syntactic
 environment objects.  In all of these functions the argument named ENV
 is an environment of the sort received by the &ENVIRONMENT argument to
 a macro or as the environment argument for EVALHOOK.  (It is not
 required that implementations provide a distinguished representation
 for such objects.)  Optional "env" arguments default to NIL, which
 represents the local null lexical environment (containing only global
 definitions and proclamations that are present in the runtime
 environment).  All of these functions should signal an error of type
 TYPE-ERROR if the value of an environment argument is not a syntactic
 environment.

 The accessors VARIABLE-INFORMATION, FUNCTION-INFORMATION, and 
 DECLARATION-INFORMATION retrieve information about declarations that
 are in effect in the environment.  Since implementations are
 permitted to ignore declarations (except for SPECIAL declarations),
 these accessors are required only to return information about
 declarations that were explicitly added to the environment using
 AUGMENT-ENVIRONMENT.  Implementations are also permitted to
 canonicalize declarations, so the information returned by the
 accessors may not be identical to the information that was passed to
 AUGMENT-ENVIRONMENT.


 VARIABLE-INFORMATION variable &optional env		[Function]

  This function returns information about the interpretation of the
  symbol VARIABLE when it appears as a variable within the lexical 
  environment ENV.  The following four values are returned.

  The first value indicates the type of definition or binding which is
  apparent in ENV:

    NIL            There is no apparent definition or binding for variable.
    :SPECIAL       VARIABLE refers to a special variable, either declared 
                   or proclaimed. 
    :LEXICAL       VARIABLE refers to a lexical variable.
    :SYMBOL-MACRO  VARIABLE refers to a SYMBOL-MACROLET binding.
    :CONSTANT      VARIABLE refers to a named constant, defined by
                   DEFCONSTANT.

 [Note: If issue PROCLAIM-LEXICAL passes, then the :LEXICAL result
  will also refer to variables proclaimed lexical.]

  The second value indicates whether there is a local binding of the
  name.  If the name is locally bound, the second value is true.
  Otherwise, NIL is returned.  

  The third value is the type specifier associated with the variable
  named by the symbol in the environment.  If no explicit association
  exists, either by PROCLAIM or DECLARE, then the result is the type
  specifier T.  It is permissible for implementations to return a type
  specifier that is equivalent to or a supertype of the one appearing 
  in the original declaration.
  
  The fourth value is a property list of containing information about
  declarations that apply to the apparent binding of the variable.
  The keys in the property list are symbols which name
  declaration-specifiers, and the format of the corresponding values
  depends on the particular declaration-specifier involved.  The only
  standard declaration-specifier that may appear as a key in this
  property list is IGNORE, with a non-NIL value to indicate that the
  variable has been declared IGNORE.  If an implementation supports
  additional declaration-specifiers that apply to variable bindings,
  those declaration-specifiers may also appear in the property list.

  Programmers are reminded that the global binding type may differ from
  the local one, and can be retrieved by calling VARIABLE-INFORMATION
  again with a null lexical environment.


 FUNCTION-INFORMATION function &optional env		[Function]

  This function returns information about the interpretation of the
  function name FUNCTION when it in a functional position within
  lexical environment ENV.  The following four values are returned.

  The first value indicates the type of definition or binding of
  the function name which is apparent in ENV:

    NIL            There is no apparent definition for FUNCTION.
    :FUNCTION      FUNCTION refers to a function.
    :MACRO         FUNCTION refers to a macro.
    :SPECIAL-FORM  FUNCTION refers to a special form.

  Some function names may refer to both a global macro and a global
  special form.  In such a case, the macro takes precedence, and
  :MACRO is returned as the first value.

  The second value specifies whether the definition is local or
  global.  If local, the second value is true, and it is false when
  the definition is global. 

  The third value is the type specifier associated with the function
  in the environment, or the symbol FUNCTION if there is no functional
  type declaration or proclamation associated with the function.  This
  value might not include all the apparent FTYPE declarations for
  FUNCTION.  It is permissible for implementations to return a type 
  specifier that is equivalent to or a supertype of the one that
  appeared in the original declaration.

  The fourth value is a property containing informatin about
  declarations that apply to the apparent binding of the function.
  The keys in the property list are symbols which name
  declaration-specifiers, and the format of the corresponding values
  depends on the particular declaration-specifier involved.  The only
  standard declaration-specifiers that may appear as a key in this
  property list are INLINE and NOTINLINE, with a non-NIL value to
  indicate that the function has been declared INLINE or NOTINLINE
  (respectively).  If an implementation supports additional
  declaration-specifiers that apply to function bindings, those
  declaration-specifiers may also appear in the property list.

  [Note: The use of "function name" rather than "symbol" as the
   description of the function argument is intended to be compatible
   with the various proposals to extend the syntax of function
   specifiers.  If no such change actually occurs then this would only
   refer to symbols.]


 AUGMENT-ENVIRONMENT env &KEY variable
			      symbol-macro
                              function
                              macro
                              declare				[Function]

  This function returns a new environment containing the information
  present in ENV, augmented with the information provided by the keyword
  arguments.  It is intended to be used by program analyzers that perform
  a code walk.

  The arguments are supplied as follows:

  :VARIABLE	A list of symbols which shall be visible as bound
		variables in the new environment.  Whether each
		binding is to be interpreted as special or lexical
		depends on SPECIAL declarations recorded in the
		environment or provided in the :DECLARE argument list.

  :SYMBOL-MACRO A list of symbol macro definitions, specified as a
                list of (name definition) lists (that is, in the same
                format as the CADR of a SYMBOL-MACROLET special form).
		The new environment will have local symbol-macro bindings
		of each symbol to the corresponding expansion, so that
		MACROEXPAND will be able to expand them properly.

  :FUNCTION	A list of function names which shall be visible as local
		function bindings in the new environment.

  :MACRO	A list of local macro definitions, specified as a
                list of (name definition) lists.  Each definition must
                be a function of two arguments (a form and an environment).
                The new environment will have local macro bindings of each
		name to the corresponding expander function, which
		will be returned by MACRO-FUNCTION and used by
		MACROEXPAND.

  :DECLARE	A list of decl-specs.  Information about these 
                declarations can be retrieved from the resulting
                environment using the VARIABLE-INFORMATION,
                FUNCTION-INFORMATION, and DECLARATION-INFORMATION
		accessors.

  An error is signalled if any of the symbols naming macros in the
  :SYMBOL-MACRO alist are also included in the :VARIABLE list.
  An error is signalled if any of the names specified as keys in the
  :MACRO alist are also included in the :FUNCTION list.  The consequences
  of destructively modifying the list structure of any of the arguments
  to this function are undefined.

  The extent of the returned environment is the same as the extent of
  the argument environment.  The result may share structure with the
  argument environment, but the argument environment is not modified.

  While an environment argument from EVALHOOK is permitted to be used
  as the environment argument for this function, the reverse is not
  true.  If an attempt is made to use the result of AUGMENT-ENVIRONMENT 
  as the environment argument for EVALHOOK, the consequences are
  undefined.  The environment returned by AUGMENT-ENVIRONMENT may only
  be used for syntactic analysis, ie. the functions specified by this
  proposal and functions such as MACROEXPAND.


 PARSE-MACRO name lambda-list body &optional env	[Function]

  This function is used to process a macro definition in the same way
  as DEFMACRO and MACROLET.  It returns a lambda-expression that accepts
  two arguments (a form and an environment).  The "name", "lambda-list",
  and "body" arguments correspond to the parts of a DEFMACRO or MACROLET
  definition.

  The "lambda-list" argument may include &ENVIRONMENT and &WHOLE.
  The "name" argument is used to enclose the "body" in an implicit
  BLOCK, and may also be used for implementation-dependent purposes
  (such as including the name of the macro in error messages if the
  form does not match the lambda-list).


 ENCLOSE lambda-expression &optional env		[Function]

  This function returns an object of type FUNCTION that is equivalent
  to what would be obtained by evaluating `(FUNCTION ,LAMBDA-EXPRESSION)
  in syntactic environment ENV.  The consequences are undefined if any
  of the local variable or function bindings that are visible in the
  lexical environment represented by ENV are referenced within the
  LAMBDA-EXPRESSION.


 DECLARATION-INFORMATION decl-spec &optional env	[Function]

  This function returns a list of declaration-specifiers whose CAR
  is the symbol DECL-SPEC that are in force in the environment ENV,
  sorted so that the most recent declaration is first on the list.
  Only declarations that do not apply to function or variable 
  bindings (i.e., those that are "pervasive") can be accessed with
  this function.

  It is required that this function recognize OPTIMIZE and DECLARATION
  as DECL-SPECs.  If an implementation has been extended to recognize
  additional pervasive declaration specifiers in DECLARE or PROCLAIM,
  it is required that either the DECLARATION-INFORMATION function
  should also recognize those declarations, or that the implementation
  provide an accessor that is specialized for that declaration
  specifier.


Rationale:

  This proposal defines a minimal set of accessors (VARIABLE-INFORMATION,
  FUNCTION-INFORMATION, and DECLARATION-INFORMATION) and a constructor
  (AUGMENT-ENVIRONMENT) for environments.

  The PARSE-MACRO function is provided so that users don't have to
  write their own code to destructure macro arguments.  Most
  implementations probably already have a similar internal function.

  The ENCLOSE function is necessary to support early evaluation of
  defining macros such as DEFMACRO by a program analyzer.  It is
  also necessary to support the revised MACROLET semantics proposed in
  issue DEFINING-MACROS-NON-TOP-LEVEL; all implementations would be
  required to have similar functionality internally.

  Making declarations from an &ENVIRONMENT or EVALHOOK environment
  optional continues to allow implementations the freedom to simply
  ignore all such declarations in the compiler or interpreter.


Examples:

#1:  This example illustrates the first value returned by the function
     VARIABLE-INFORMATION.

  (DEFMACRO KIND-OF-VARIABLE (VAR &ENVIRONMENT ENV)
    `',(VARIABLE-INFORMATION VAR ENV))

  (DEFVAR A)

  (DEFUN TEST ()
    (LET (B)
      (LET (C)
        (DECLARE (SPECIAL C))
        (SYMBOL-MACROLET ((D ANYTHING))
          (LIST (KIND-OF-VARIABLE A)
                (KIND-OF-VARIABLE B)
                (KIND-OF-VARIABLE C)
                (KIND-OF-VARIABLE D)
                (KIND-OF-VARIABLE E))))))

  (TEST) -> (:SPECIAL :LEXICAL :SPECIAL :SYMBOL-MACRO NIL)
      

#2:  This example illustrates the first value returned by the function
     FUNCTION-INFORMATION.

  (DEFMACRO KIND-OF-FUNCTION (FUNCTION-NAME &ENVIRONMENT ENV)
    `',(FUNCTION-INFORMATION FUNCTION-NAME ENV))

  (DEFUN A ())

  (DEFMACRO B ())

  (DEFUN TEST ()
    (FLET ((C ()))
      (MACROLET ((D ()))
        (MULTIPLE-VALUE-CALL #'LIST
              (KIND-OF-FUNCTION A)
              (KIND-OF-FUNCTION B)
              (KIND-OF-FUNCTION QUOTE)
              (KIND-OF-FUNCTION C)
              (KIND-OF-FUNCTION D)
              (KIND-OF-FUNCTION E)))))

  (TEST) -> (:FUNCTION      NIL
             :MACRO         NIL
             :SPECIAL-FORM  NIL
             :FUNCTION      T
             :MACRO         T
             NIL            NIL)


#3:  This example shows how a code-walker might walk a MACROLET special
     form.  It assumes that the revised MACROLET semantics described in
     proposal DEFINING-MACROS-NON-TOP-LEVEL:ALLOW are in effect.

(defun walk-macrolet (form env)
    (let ((macros  (make-macro-definitions (cadr form) env)))
	(multiple-value-bind (body decls) (parse-body (cddr form))
	    (walk-implicit-progn
	        body
		(augment-environment env :macro macros :declare decls))
             )))


(defun make-macro-definitions (defs env)
    (let ((results  nil))
	(dolist (d defs)
	    (push (list (car d)
			(enclose (parse-macro (car d) (cadr d) (cddr d) env)
				 env))
		  results))
	results))


Cost to Implementors:

 Most implementations already record some of this information in some
 form.  Providing these functions should not be too difficult, but it
 is a more than trivial amount of work.

Cost to Users:

 This change is upward compatible with user code.

Current practice:

 No implementation provides all of this interface currently.  Portable
 Common Loops defines a subset of this functionality for its code
 walker and implements it on a number of diffent versions of Common
 Lisp.

Discussion:

 The first version of this proposal expressly did not deal with the
 objects which are used as environments by EVALHOOK.  This version is
 extended to support them in the belief that such environments share a
 lot of functionality with the syntactic environments needed by a
 compiler.  While the two types of environments might have very
 different implementations, there are many operations which are
 reasonable to perform on either type, including all of the accessor
 functions described by this proposal.

 AUGMENT-ENVIRONMENT currently requires signaling an error when
 symbol-macro names match variable names in the same call.  This could
 be reduced to "should signal".  By requiring the error signaling, this
 proposal is compatable with Proposal SYMBOL-MACROLET-DECLARE:ALLOW,
 which says

   "... signals an error if a SPECIAL declaration names one of the symbols
   being defined as a symbol-macrolet."

 Maintaining compatability with the SYMBOL-MACROLET-DECLARE proposal
 allows fairly trivial implementations of the SYMBOL-MACROLET
 special-form in terms of the AUGMENT-ENVIRONMENT function.

 Moon notes:
  Symbolics Genera includes an undocumented internal macro, used
  quite a bit in the implementation of the interpreter and code
  analyzers, that could have been called WITH-AUGMENTED-ENVIRONMENT,
  taking keywords like AUGMENT-ENVIRONMENT and also body forms,
  and producing an environment with dynamic extent bound to a
  variable within the body forms.  Would it be useful to have this
  too, or instead of AUGMENT-ENVIRONMENT?  I'm unsure.

 Some people have indicated they think that the :MACRO argument (and
 the :SYMBOL-MACRO argument too?) to AUGMENT-ENVIRONMENT should be an
 a-list of the form (name . definition).

 Some people have indicated they think that implementations must never
 discard any declarations, even if they are not otherwise used by the
 interpreter or compiler.  Proposal SMALL is consistent with what CLtL 
 says (implementations are free to ignore all declarations except
 SPECIAL declarations), but the DECLARATION-INFORMATION function may
 not be particularly useful unless it is guaranteed to do something.
 Requiring implementations to keep track of declarations they'd otherwise
 ignore would involve some implementation cost and also may incur a
 performance penalty.
-------

∂23-Mar-89  1527	X3J13-mailer 	issue EVAL-WHEN-NON-TOP-LEVEL, version 7 
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89  15:25:15 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA14465; Thu, 23 Mar 89 14:45:11 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA12759; Thu, 23 Mar 89 14:45:06 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903232145.AA12759@defun.utah.edu>
Date: Thu, 23 Mar 89 14:45:03 MST
Subject: issue EVAL-WHEN-NON-TOP-LEVEL, version 7
To: x3j13@sail.stanford.edu

A paragraph on order of processing of top-level forms (which used to be
discussed in issue DEFINING-MACROS-NON-TOP-LEVEL) has been added to
this version of the writeup.

Issue:        EVAL-WHEN-NON-TOP-LEVEL
Forum:        Compiler
References:   EVAL-WHEN (CLtL pp69-70),
              Issue DEFINING-MACROS-NON-TOP-LEVEL
	      Issue COMPILED-FUNCTION-REQUIREMENTS
	      Issue IN-PACKAGE-FUNCTIONALITY
	      Issue LOCALLY-TOP-LEVEL
Category:     CLARIFICATION/CHANGE
Edit History: 06-May-88, Version 1 by Sandra Loosemore
              16-Dec-88, Version 2 by Loosemore (alternate direction)
              30-Dec-88, Version 3 by Loosemore (minor wording changes)
              07-Jan-89, Version 4 by Loosemore (update discussion)
              09-Feb-89, Version 5 by Pitman and Moon (some major changes)
	      09-Mar-89, Version 6 by Loosemore (clean up wording)
	      22-Mar-89, Version 7 by Loosemore (order of processing)
Status:       Ready for release

Problem Description:

  The current description of how the compiler should handle EVAL-WHEN
  only makes sense when it appears as a top-level form in the file being
  compiled. Is it legitimate for EVAL-WHEN to appear in non-top-level
  locations? Even if it is legitimate, what does it mean?
 
  Another issue, referred to here as ``the EVAL-WHEN shadowing problem,''
  is that some people have complained that shadowing the symbols EVAL,
  COMPILE, or LOAD means that you have to also either shadow EVAL-WHEN
  and define it to recognize the new symbol, or else you must resign
  yourself to writing (EVAL-WHEN (... LISP:EVAL ...) ...),etc. all over.
  While the goal here is not to solve this problem, it might be possible
  to solve both problems at once.

  There are two proposals presented here, GENERALIZE-EVAL and
  GENERALIZE-EVAL-NEW-KEYWORDS.


Background/Analysis:

  The proposal which follows was constructed with the following goals
  in mind:

    1. The lexical and dynamic environment for the EVAL-WHEN body should
       be the same for each situation.  That is, the body should ``mean
       the same thing'' regardless of which situation is being processed.

    2. The evaluation context for EVAL-WHEN should be the current
       lexical environment.

    3. At execution time, EVAL-WHEN should always return the result of
       its last form if execution of the body occurred, or NIL if the
       body was not executed.

    4. If a top-level EVAL-WHEN has a LOAD keyword, its body should 
       inherit top-level-ness during normal processing. This permits the
       use of (EVAL-WHEN (EVAL COMPILE LOAD) ...) at top-level to mean
       simply "Do whatever would normally be done for this body, but
       also do something at compile time." This, in turn, will later be
       the key to allowing defining forms to be usefully described in
       terms of EVAL-WHEN.

    5. Non-top-level expressions should have no effect until they are
       executed. This is the key to making sure that any necessary
       environment is present. Since the COMPILE keyword forces effects
       to occur earlier than execution time, it follows from this that
       any correct solution must not allow the COMPILE keyword to have
       an effect at other than top-level.

  To accomplish these goals, we formulated the following model:

    The purpose of EVAL-WHEN is to accomodate the fact that some of the
    semantic processing of an expression may usefully be partitioned
    between compile time and run time in some circumstances.

    (EVAL-WHEN (EVAL) <code>)
    describes a general technique for accomplishing some particular goal
    at normal program execution time. However, the pair of expressions
    (EVAL-WHEN (COMPILE) <code-A>)
    (EVAL-WHEN (LOAD) <code-B>)
    can be used to describe an alternate technique for implementing part
    of the effect (A) at compile-time, and part of the effect (B) at
    load-time.


Proposal (EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL):

  Replace the description of EVAL-WHEN with the following:

  EVAL-WHEN ({situation}*) {form}*                      [Special Form]

  The body of an EVAL-WHEN form is processed as an implicit PROGN, but
  only in the situations listed.  Each SITUATION must be a symbol,
  either COMPILE, LOAD, or EVAL.

  The use of COMPILE and LOAD controls whether and when processing
  occurs for top-level forms. The use of EVAL controls whether
  processing occurs for non-top-level forms.

  The EVAL-WHEN construct may be more precisely understood in terms of
  a model of how the file compiler, COMPILE-FILE, processes forms in a
  file to be compiled.

  Successive forms are read from the file by the file compiler using 
  READ. These top-level forms are normally processed in what we call
  `not-compile-time' mode. There is one other mode, called 
  `compile-time-too' mode, which can come into play for top-level
  forms. The EVAL-WHEN special form is used to annotate a program
  in a way that allows the program doing the processing to select
  the appropriate mode.

  Processing of top-level forms in the file compiler works as follows:

   * If the form is a macro call, it is expanded and the result is
     processed as a top-level form in the same processing mode
     (compile-time-too or not-compile-time).

   * If the form is a PROGN form, each of its body forms is
     sequentially processed as top-level forms in the same processing
     mode.

   * If the form is a COMPILER-LET, MACROLET, or SYMBOL-MACROLET,
     the file compiler makes the appropriate bindings and recursively
     processes the body forms as an implicit top-level PROGN with those 
     bindings in effect, in the same processing mode.

   * If the form is an EVAL-WHEN form, it is handled according to
     the following table:

     COMPILE LOAD EVAL compile-time-too Action
     
       Yes   Yes  --     --             Process body in compile-time-too mode
       No    Yes  Yes    Yes            Process body in compile-time-too mode
       No    Yes  Yes    No             Process body in not-compile-time mode
       No    Yes  No     --             Process body in not-compile-time mode
       Yes   No   --     --             Evaluate body
       No    No   Yes    Yes            Evaluate body
       No    No   Yes    No             do nothing
       No    No   No     --             do nothing

     "Process body" means to process the body as an implicit top-level
     PROGN.  "Evaluate body" means to evaluate the body forms as in
     implicit PROGN in the dynamic execution context of the compiler and
     in the lexical environment in which the EVAL-WHEN appears.

   * Otherwise, the form is a top-level form that is not one of the
     special cases.  If in compile-time-too mode, the compiler first
     evaluates the form and then performs normal compiler processing
     on it.  If in not-compile-time mode, only normal compiler
     processing is performed.  [The nature of this processing is
     defined more precisely in issue COMPILED-FUNCTION-REQUIREMENTS.]
     Any subforms are treated as non-top-level forms.

  Note that top-level forms are guaranteed to be processed in the order
  in which they textually appear in the file, and that each top-level
  form read by the compiler is processed before the next is read.
  However, the order of processing (including, in particular, macro
  expansion) of subforms that are not top-level forms is unspecified.

  For an EVAL-WHEN form that is not a top-level form in the file compiler
  (that is, one of: in the interpreter; in COMPILE; or in the file
  compiler but not at top-level), if the EVAL situation is specified,
  its body is treated as an implicit PROGN.  Otherwise, the EVAL-WHEN
  form returns NIL.


 Clarifications/Consequences:

  The following effects are logical consequences of the above proposal:

   * It is never the case that the execution of a single EVAL-WHEN
     expression will execute the body code more than once.

   * The keyword `EVAL' is a misnomer because execution of
     the body need not be done by EVAL. In compiled code, such as
     (DEFUN FOO () (EVAL-WHEN (EVAL) (PRINT 'FOO)))
     the call to PRINT should be compiled.

   * Macros intended for use in top-level forms should arrange for all
     side-effects to be done by the forms in the macro expansion.
     The macro-expander itself should not do the side-effects.

       Wrong:  (defmacro foo ()
                 (really-foo)
                 `(really-foo))
    
       Right:  (defmacro foo ()
                 `(eval-when (compile eval load) (really-foo)))

     Adherence to this convention will mean that such macros will behave
     intuitively when placed in non-top-level positions.

   * Placing a variable binding around an EVAL-WHEN reliably captures the
     binding because the `compile-time-too' mode cannot occur (because 
     introducing a variable binding would mean we were not at top level).
     For example,

        (LET ((X 3))
          (EVAL-WHEN (EVAL LOAD COMPILE) (PRINT X)))

     will print 3 at execution [load] time, and will not print anything at
     compile time.  This is important so that expansions of DEFUN and 
     DEFMACRO can be done in terms of EVAL-WHEN and can correctly capture
     the lexical environment.

        (DEFUN BAR (X) (DEFUN FOO () (+ X 3)))

     might expand into

        (DEFUN BAR (X) 
          (PROGN (EVAL-WHEN (COMPILE) 
                   (COMPILER::NOTICE-FUNCTION-DEFINITION 'FOO '(X)))
                 (EVAL-WHEN (EVAL LOAD)
                   (SETF (SYMBOL-FUNCTION 'FOO) #'(LAMBDA () (+ X 3))))))

     which would be treated the same as

        (DEFUN BAR (X) 
          (SETF (SYMBOL-FUNCTION 'FOO) #'(LAMBDA () (+ X 3))))

     by the above rules.


 Test Cases:

  ;; #1: The EVAL-WHEN in this case is not at top-level, so only the EVAL
  ;;     keyword is considered. At compile time, this has no effect.
  ;;     At load time (if the LET is at top level), or at execution time
  ;;     (if the LET is embedded in some other form which does not execute
  ;;     until later) this sets (SYMBOL-FUNCTION 'FOO1) to a function which
  ;;     returns 1.
 
  (LET ((X 1))
    (EVAL-WHEN (EVAL LOAD COMPILE)
      (SETF (SYMBOL-FUNCTION 'FOO1) #'(LAMBDA () X))))
 
  ;; #2: If this expression occurs at the top-level of a file to be compiled,
  ;;     it has BOTH a compile time AND a load-time effect of setting
  ;;     (SYMBOL-FUNCTION 'FOO2) to a function which returns 2.
 
  (EVAL-WHEN (EVAL LOAD COMPILE)
    (LET ((X 2))
      (EVAL-WHEN (EVAL LOAD COMPILE)
        (SETF (SYMBOL-FUNCTION 'FOO2) #'(LAMBDA () X)))))
 
  ;; #3: If this expression occurs at the top-level of a file to be compiled,
  ;;     it has BOTH a compile time AND a load-time effect of setting the
  ;;     function cell of FOO3 to a function which returns 3.
 
  (EVAL-WHEN (EVAL LOAD COMPILE)
    (SETF (SYMBOL-FUNCTION 'FOO3) #'(LAMBDA () 3)))
 
  ;; #4: This always does nothing. It simply returns NIL.
 
  (EVAL-WHEN (COMPILE)
    (EVAL-WHEN (COMPILE) 
      (PRINT 'FOO4)))
 
  ;; #5: If this form occurs at top-level of a file to be compiled, FOO5 is
  ;;     printed at compile time. If this form occurs in a non-top-level
  ;;     position, nothing is printed at compile time. Regardless of context,
  ;;     nothing is ever printed at load time or execution time.
 
  (EVAL-WHEN (COMPILE) 
    (EVAL-WHEN (EVAL)
      (PRINT 'FOO5)))

  ;; #6: If this form occurs at top-level of a file to be compiled, FOO6 is
  ;;     printed at compile time.  If this form occurs in a non-top-level
  ;;     position, nothing is printed at compile time. Regardless of context,
  ;;     nothing is ever printed at load time or execution time.

  (EVAL-WHEN (EVAL LOAD)
    (EVAL-WHEN (COMPILE)
      (PRINT 'FOO6)))
 
 Rationale:
  
  This is compatible with any guarantees made by CLtL, and extends the
  behavior usefully to non-top-level situations.

  This gives a useful meaning to EVAL-WHEN that supports useful and
  predictable behavior if defining macros are used in a non-top-level
  situation.

  The constraints on the order in which top-level forms are processed
  ensure that the compile-time effects of defining macros and EVAL-WHENs
  at the beginning of the file are visible during the processing of
  forms that appear later in the file, which is what most users expect.
  Leaving the order of processing of non-top-level forms unspecified
  allows the compiler to perform certain kinds of transformations that
  change the textual order of subforms.  Users should not depend on 
  side-effects from macros that require them to be expanded in any
  particular order.


Proposal (EVAL-WHEN-NON-TOP-LEVEL:GENERALIZE-EVAL-NEW-KEYWORDS):

  As in GENERALIZE-EVAL, but rename the EVAL keyword to :EXECUTE,
  the COMPILE keyword to :COMPILE-TOPLEVEL, and LOAD keyword to 
  :LOAD-TOPLEVEL.

  Deprecate the use of keywords EVAL, COMPILE, and LOAD to EVAL-WHEN.
  For compatibility, they are supported in EVAL-WHEN
  at top-level, but their meaning is not defined elsewhere.

 Rationale:

  The fact that the situation keywords chosen are not the same as
  those now used means that the change can be added in a way that
  is truly upward compatible (not only with CLtL but with existing
  practice in implementations which have chosen to extend or `clarify'
  the definition given in CLtL) since the meaning of EVAL, COMPILE,
  and LOAD in non-top-level situations (which was never spelled
  out in CLtL) can legitimately differ from the meaning of these
  new keywords.

  Using other names and/or the keyword package for the names of
  situations solves the EVAL-WHEN shadowing problem.

  The name `execute' does not promote the confusion that the body of an
  EVAL-WHEN must be executed only in the evaluator. It also does not
  promote the confusion that the body of an EVAL-WHEN, regardless of when
  executed, must run interpreted.

  The names `compile-toplevel' and `load-toplevel' emphasize the fact
  that these cases are not interesting in non-top-level positions.


Current Practice:

  In Symbolics Genera, the interpreter permits EVAL-WHEN in non-top-level 
  positions in a way that is compatible with this proposal but both the
  COMPILE and COMPILE-FILE functions complain about EVAL-WHEN in a
  non-top-level position.

  Both Lucid Common Lisp and Kyoto Common Lisp already interpret the
  EVAL keyword to mean "execute" in non-top-level situations.  Both of
  these implementations also make (EVAL-WHEN (LOAD) ...) suppress
  compile-time "magic" from defining macros such as DEFMACRO.

  IIM describes its EVAL-WHEN as:
   (defmacro eval-when (situations &body body &environment env)
     (if (not (compiler-environment-p env))
         (when (member 'eval situations) `(progn ,@body))
         (progn
           (when (member 'compile situations)
             (if (compiler-at-top-level-p env)
                 (mapc #'eval body)
                 (warn "Top-level form encountered at non-top-level.")))
           (when (member 'load situations) `(progn ,@body)))))
  Note that the interpretation of the EVAL situation and the nesting
  behavior is different.


Cost to Implementors:

  The actual change to EVAL-WHEN in both cases is probably fairly
  localized and straightforward to make in most or all implementations.

  The second-order costs of proposal GENERALIZE-EVAL will vary depending
  on whether existing implementations have extended the definition of
  EVAL-WHEN in incompatible ways. If an implementation has made such
  extensions, there may be user and system code which depends on them
  and the cost of converting that code may be non-trivial. There is
  presumably also documentation impact.

  Proposal GENERALIZE-EVAL-NEW-KEYWORDS avoids most or all of the 
  second-order costs of proposal GENERALIZE-EVAL.

  The compiler processing for top-level forms might be implemented 
  something like:

  ;;; Forms read by the file compiler are passed to PROCESS-TOP-LEVEL-FORM
  ;;;    with a env compile-time-too both NIL.
  
  (defun process-top-level-form (form env compile-time-too)
      (setq form (macroexpand form env))
      (cond ((not (consp form))
             nil)
            ((eq (car form) 'progn)
             (dolist (f (cdr form))
                 (process-top-level-form f env compile-time-too)))
            ((eq (car form) 'compiler-let)
             (process-compiler-let form env compile-time-too))
            ((eq (car form) 'macrolet)
             (process-macrolet form env compile-time-too))
            ((eq (car form) 'symbol-macrolet)
             (process-symbol-macrolet form env compile-time-too))
            ((eq (car form) 'eval-when)
             (process-eval-when form env compile-time-too))
            (t
             (if compile-time-too
                 (internal-eval form env))
             (compile-form form env))
            ))
  
  (defun process-eval-when (form env compile-time-too)
      (let* ((situations  (cadr form))
             (body        (cddr form))
             (compile-p   (member 'compile situations))
             (load-p      (member 'load situations))
             (eval-p      (member 'eval situations)))
          (cond ((or (and compile-p load-p)
                     (and eval-p load-p compile-time-too))
                 (process-top-level-form `(progn ,@body) env t))
                (load-p
                 (process-top-level-form `(progn ,@body) env nil))
                ((or compile-p
                     (and eval-p compile-time-too))
                 (dolist (f body)
                     (internal-eval f env)))
                (t
                 nil))))
  
  ;;; PROCESS-COMPILER-LET, PROCESS-MACROLET, and PROCESS-SYMBOL-MACROLET
  ;;;    do the obvious things.
  ;;; INTERNAL-EVAL evaluates "form" in lexical environment "env".


Cost to Users:

  Technically, none. Either proposal is technically upward compatible
  with CLtL.

  Proposal GENERALIZE-EVAL might force some extended implementations to
  change incompatibly. As such, some users who depend on 
  implementation-dependent extensions might have to adjust their code
  somewhat to deal with those changes.

  Proposal GENERALIZE-EVAL-NEW-KEYWORDS does not force implementations
  to change incompatibly, so has no forced impact on users.

Cost of Non-Adoption:

  EVAL-WHEN is a mess. Using it as the low-level substrate into which
  defining macros should expand, and guaranteeing any predictable effects
  of those macros in non-top-level situations is currently difficult and
  would continue to be so in the absence of some resolution on this issue.

Benefits:

  The costs of non-adoption would be avoided:  it would be possible to
  use EVAL-WHEN in many situations where it cannot currently be used
  reliably.

  The portability of many existing tools which use EVAL-WHEN internally
  in macros will be enhanced.

Aesthetics:

  This generalization of the meaning makes the purpose and uses of 
  EVAL-WHEN less mysterious. In that sense, aesthetics are simplified
  somewhat.


Discussion:

  The cleanup issue LOCALLY-TOP-LEVEL would make LOCALLY also "pass
  through" top-level-ness to its body.  The reason why that is not 
  addressed in this issue is that it involves making LOCALLY a special
  form.

  Pitman and Moon don't care whether we say `top level,' `top-level,' or
  `toplevel.' The spelling choices in this writeup are arbitrary. If
  necessary, the proposal GENERALIZE-EVAL-NEW-KEYWORDS could be amended
  to propose :COMPILE-TOP-LEVEL, etc.

  Pitman, Moon, and Bob Laddaga (a Symbolics Cloe implementor) support
  both of these proposals.  Pitman and Laddaga have a preference for
  GENERALIZE-EVAL-NEW-KEYWORDS.  Moon is neutral about which should be
  preferred.

  Sandra Loosemore says:
    I still feel somewhat uncomfortable with the definition of EVAL-WHEN
    presented here, mostly because its nesting behavior is so unintuitive
    (as in test case number 6).  We have also had a hard time in deciding
    what the term "top-level" really means; the definition presented here
    is rather arbitrary.  However, since we have run out of time in which
    to come up with acceptable alternatives, I'm willing to go along with
    proposal GENERALIZE-EVAL.  It is compatible with the description in
    CLtL but presented in a more coherent way, and I think it is an
    improvement.  On the other hand, I don't really like the idea of
    changing the names of the keywords; if we are going to make an
    incompatible change, the right thing to do would be to throw out
    EVAL-WHEN entirely and start from scratch.

  Treating MACROLET and SYMBOL-MACROLET (and possibly LOCALLY) 
  complicates the treatment of top-level DEFMACROs and other
  defining macros that cause functions to be created at compile-time
  (because the lexical environment the functions are defined in may
  not be null).  See issue DEFINING-MACROS-NON-TOP-LEVEL for details.-------

∂23-Mar-89  1538	CL-Cleanup-mailer 	The Revised Cleanup Issue Status List    
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 23 Mar 89  15:33:50 PST
Received: from Semillon.ms by ArpaGateway.ms ; 23 MAR 89 13:44:52 PST
Date: 23 Mar 89 13:43 PST
From: masinter.pa@Xerox.COM
to: cl-cleanup@sail.stanford.edu
Subject: The Revised Cleanup Issue Status List
to: X3J13@sail.stanford.edu
Message-ID: <890323-134452-5540@Xerox>

This is the revised (as of 23-Mar-89 13:43:08) complete list of
Cleanup issues that are either:

passed: passed at *any* previous meeting, including Jan 89

pending: have been distributed for the March meeting

in progress: might possibly be distributed for the March meeting,
	or that I think are worth pursuing.

Of course, some more might come up or be revived.

I think I have updated versions of all pending and passed
issues stored on arisia.xerox.com under the
	clcleanup/pending
	clcleanup/passed

directories respectively.

Codes:

! released for Jan 89 meeting
+ passed
* need new version


!*: released, but I know we'll need a new version
+*: passed, but need to reconsider
!*: passed, but need a new version to reconsider

!

+ ADJUST-ARRAY-DISPLACEMENT
Version 4, 23-Nov-87
Status: passed, 1988

+ ADJUST-ARRAY-FILL-POINTER
 Version 1, 15-MAR-88
Status: passed, 1988

! ADJUST-ARRAY-NOT-ADJUSTABLE
Synopsis: ADJUST-ARRAY on array made with :ADJUSTABLE NIL: "an error"?
Version 4, 11-Jan-89, Released 12-Jan-89
Status: Accepted with amendments Jan 89 X3J13
Comments:  amendment had wording problem.
Version 8, 11-Mar-89, Released 15-Mar-89
Version 9, 17-Mar-89, released 21-mar-89
Comments: (whew!)
Status: ready for vote 

+ APPLYHOOK-ENVIRONMENT
Synopsis: remove (useless) env argument to applyhook
Version 2, 10-Jan-89, Released 10-Jan-89
Status: Passed Jan-89 X3J13

+ AREF-1D
14-NOV-87, Version 7
Status: Passed, 1988?

+ ARGUMENTS-UNDERSPECIFIED
Synopsis: Clarify various ranges missing from CLtL
Version 4, 21-Sep-88, Released 4 Dec 88
Status: Passed Jan 89 X3J13

+ ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS
Synopsis: What do array element-type declarations mean?
Version 9, 31-Oct-88, Released 5 Dec 88
Status: Passed Jan 89 X3J13

+ ASSOC-RASSOC-IF-KEY
Version 4, 23-NOV-87
Status: Passed, 1988?

! BREAK-ON-WARNINGS-OBSOLETE
Synopsis: deprecate *BREAK-ON-WARNINGS* because of *BREAK-ON-SIGNALS*
Version 1, 07-Mar-89, Released 15-Mar-89
Comment: leaves out a case
Status: ready for vote

! CLOS-CONDITIONS
Version 4, 10-Mar-89
Comments: define metaclass of conditions? 
Status: pending

+ CLOSE-CONSTRUCTED-STREAMS
Synopsis: What does it mean to CLOSE a constructed stream?
Version 2, 12-Jan-89, Released 12-Jan-89
Status: Proposal ARGUMENT-STREAM-ONLY passed Jan 89 X3J13

!+ CLOSED-STREAM-OPERATIONS
Synopsis: What operations are legal on closed streams?
Version 5, 5-Dec-88, released 5-Dec-88
Status: amended at meeting
Version 7, 14-Feb-89
Status: Passed, as amended, Jan 89 X3J13
Comment: amendment bad; reconsider version 5.
	say that INPUT-STREAM-P and OUTPUT-STREAM-P
	are undefined on closed streams?

! COERCE-INCOMPLETE
Synopsis: Extend COERCE
Version 3, 7-Mar-89, Released 14-Mar-89
Status: ready for voting

+ COLON-NUMBER
Synopsis:  :123 is an error
22-OCT-87, Version 1
Status: Passed, 1988?

! COMMON-TYPE
Version 1, 20-Mar-89, released 21-Mar-89
Status: vote

! COMPLEX-RATIONAL-RESULT
Version 1, 20-Mar-89, released 21-Mar-89
Status: vote

+ COMPILER-WARNING-STREAM
Version 6, 5-JUN-87
Status: Passed, 1988?

+ COMPLEX-ATAN-BRANCH-CUT
Synopsis: tweak upper branch cut in ATAN formula
Version 1, 13-Dec-88, Released 10-Jan-89
Status: Passed Jan 89 X3J13

!* CONDITION-RESTARTS
Synopsis: can't know whether restart is associated with signalling
Version 1, 18-Jan-89, released 16-Mar-89
Comment: (proposed amendments)
Status: need new version

+ CONTAGION-ON-NUMERICAL-COMPARISONS
Version 1, 14-Sep-88, Released 6 Oct 88
Status: passed, Jan 89 X3J13

! COPY-SYMBOL-COPY-PLIST
Version 1, 10-Jan-89, released 16-Mar-89
Status: ready for vote

! COPY-SYMBOL-PRINT-NAME
Version 2, 15-Mar-89, released 16-Mar-89
Status: ready for vote

+ DATA-TYPES-HIERARCHY-UNDERSPECIFIED
4-SEP-88 Version 2
Status: Passed, 1988?

+ DECLARATION-SCOPE
Version 4, 15-Nov-88, Released 9-Dec-88
Status: NO-HOISTING passed Jan 89 X3J13

+ DECLARE-ARRAY-TYPE-ELEMENT-REFERENCES
Version 3, 13-Jan-89
Status: passed, Jan 89 X3J13

+ DECLARE-FUNCTION-AMBIGUITY
Version 4,  5-Dec-88, Released  5-Dec-88
Status: passed, Jan 89 X3J13

+ DECLARE-MACROS
5-FEB-88, Version 3
Status: Passed, 1988?

+ DECLARE-TYPE-FREE
Version 10, 12-Jan-89
Status: proposal LEXICAL passed Jan 89 X3J13

+ DECODE-UNIVERSAL-TIME-DAYLIGHT
Version 2, 30-Sep-88, Released 6 Oct 88
Status: Passed, Jan 89 x3j13

* DEFMACRO-LAMBDA-LIST
Version 2, 17-Mar-89
Status: ** NEED NEW VERSION **

+ DEFPACKAGE
Version 7, 2-Nov-88, Released 5 Dec 88
Comment: clarify "at variance" in editorial work?
Status: Passed, Jan 89 X3J13

+ DEFSTRUCT-CONSTRUCTOR-KEY-MIXTURE
Version 3, 8-Jan-89, Released 11-Jan-89
Status: Passed, Jan 89 X3J13

+ DEFSTRUCT-DEFAULT-VALUE-EVALUATION
Version 1, 5/13/88
Status: Passed, 1988

+ DEFSTRUCT-PRINT-FUNCTION-INHERITANCE
Version 3, 7 Dec 88, Released 12-Dec-88
Status: Passed, Jan 89 X3J13

+ DEFSTRUCT-REDEFINITION
Synopsis: what happens if you redefine a DEFSTRUCT?
Version 3, 6-Feb-89
Status: Passed (as amended) Jan 89 X3J13

+ DEFSTRUCT-SLOTS-CONSTRAINTS-NAME
Version 5, 12-Jan-89
Status: Passed, Jan 89 X3J13

+ DEFSTRUCT-SLOTS-CONSTRAINTS-NUMBER
Version 1, 5/13/88
Status: Passed, 1988

+ DEFVAR-DOCUMENTATION
23-NOV-87, Version 2
Status: Passed, 1988?

+ DEFVAR-INIT-TIME
29-MAR-87, Version 2
Status: Passed, 1988?

+ DEFVAR-INITIALIZATION
Version 4 5-JUN-87
Status: Passed, 1988?

+ DESCRIBE-INTERACTIVE
Version 4, 15-Nov-88, Released 7-Dec-88
Synopsis: can DESCRIBE ask user a question?
Status: Proposal NO passed Jan 89 X3J13

! DESCRIBE-UNDERSPECIFIED
Version 1, 10-Mar-89, Released 16-Mar-89
Synopsis: making DESCRIBE generic was wrong; fix
Comments: "and calls DESCRIBE recursively argument if there are ... "
status: need to strike "argument"; then vote

!* DESTRUCTURING-BIND
Version 2, 25-Jan-89, Released 16-Mar-89
Synopsis: add DESTRUCTURING-BIND macro
Comments: (at end) + "can't extend by defining harmless...????"
Status: might need new version before vote

+ DISASSEMBLE-SIDE-EFFECT
Version 3 1/21/88
Status: Passed, 1988

+ DO-SYMBOLS-DUPLICATES
Version 3 23-NOV-87
Status: Passed, 1988?

+ DOTTED-MACRO-FORMS
Version 3, 15-Nov-88, Released 7-Dec-88
Status: passed, Jan 89 X3J13

+ DRIBBLE-TECHNIQUE
14-FEB-88, Version 2
Status: Passed, 1988?

! DYNAMIC-EXTENT
Version 3, 11-Jan-89, released 16-Mar-89
Comments: still some holes
Status: ready for vote?

+ EQUAL-STRUCTURE
Version 6, 11-Jan-89, Released 12-Jan-89
Status: Passed with amendments
Version 7, 15-Mar-89
Status: Passed Jan 89 X3J13 as amended.

* EQUALP-GENERIC
Version 1, 28-Feb-89
Synopsis: make EQUALP generic function
Comments: Various problems being worked on
Status: ** NEED NEW VERSION ***

* ERROR-CHECKING-IN-NUMBERS-CHAPTER
Version 1, 6-Mar-89
Synopsis: define 'should signal', 'might signal' for number fns
Status: ** NEED NEW VERSION **

! ERROR-NOT-HANDLED
Version 1, 25-Sep-88, Released 6-Oct-88 and 14-Mar-89
Status: ready for vote

+ EVAL-OTHER
8-JUN-88, Version 2
Status: Passed, 1988?

! EXIT-EXTENT
Version 6,  8-Jan-89, distributed at Jan89 X3J13
Rereleased 16-Mar-89
Status: tabled Jan89; ready for vote

+ EXPT-RATIO
Version 3, 31-Oct-88, Released 7 Dec 88
Status: passed, Jan 89 X3J13

+ FIXNUM-NON-PORTABLE
Version 4, 7-Dec-88, Released 12-Dec-88
Version 6, 17-Mar-89, as amended
Status: Passed, Jan 89 X3J13, as amended

+ FLET-DECLARATIONS
Version 2, 2 FEB 88
Status: Passed, 1988?

+ FLET-IMPLICIT-BLOCK
Version 6 5-JUN-87
Status: Passed, 1988?

+ FORMAT-ATSIGN-COLON
Version 4 5-JUN-87
Status: Passed, 1988?

+ FORMAT-COLON-UPARROW-SCOPE
Version 3, 5 FEB 88
Status: Passed, 1988?

+ FORMAT-COMMA-INTERVAL
Version 2, 15-JUN-87
Status: Passed, 1988?

+ FORMAT-E-EXPONENT-SIGN
Version 2, 2 Oct 88, Released 6 Oct 88
Status: Passed, Jan 89 X3J13

+ FORMAT-OP-C
11-JUN-87, Version 5
Status: Passed, 1988?

* FORMAT-PLURALS
Synopsis: remove ~P, add ~:@[singular~;plural~]
Status: no proposal

+ FORMAT-PRETTY-PRINT
Version 7, 15 Dec 88, Released 7 Dec 88
Comments: passed, Jan 89 X3j13

+ FUNCTION-CALL-EVALUATION-ORDER
Version 1, 22-MAR-88
Status: Passed, 1988

! FUNCTION-COERCE-TIME
Synopsis: When does SYMBOL-FUNCTION happen in MAPCAR?
Version 2, 16-sep-88, Released 8-Oct-88
Re-released: 16-Mar-89
Status: ready for vote?

+ FUNCTION-COMPOSITION
Synopsis: Add new functions
Version 5, 10-Feb-89 
Status: Passed (as amended) Jan 89 X3J13
     maybe this was passed as amendment to TEST-NOT-IF-NOT instead

+ FUNCTION-DEFINITION
Version 3, 10-Feb-89
Status: Passed (as amended) Jan 89 X3J13

! FUNCTION-NAME
Comment: renaming of SETF-FUNCTION-VS-MACRO, SETF-PLACES
SETF-FUNCTION-VS-MACRO
 Version 3, 4-Nov-87, Released Nov 87
SETF-PLACES
 Version 1, 11-Nov-88, Released 9-Dec-88
FUNCTION-NAME
 Version 1, 27-Jan-89, Released 16-Mar-89
Status: ready for vote

+ FUNCTION-TYPE
Version 12, 4-SEP-88
Status: Passed, June 1988 X3J13, as amended

+ FUNCTION-TYPE-ARGUMENT-TYPE-SEMANTICS
Synopsis: Change semantics of argument types in function declarations
Version 3, 7-Dec-88, Released  12-Dec-88
Status: Passed, Jan 89 X3J13

+ FUNCTION-TYPE-KEY-NAME
Version 3, 13-FEB-88 
Status: Passed, 1988

+ FUNCTION-TYPE-REST-LIST-ELEMENT
Version 5, 14-Nov-88, Released 8-Dec-88
Status: Passed, Jan 89 X3J13

! GENSYM-NAME-STICKINESS
Synopsis: no side effects if optional arg supplied
Version 1, 14-Feb-89, Released 14-Mar-89
Status: comments
Version 3, 20-Mar-89
Status: vote? 

+ GET-MACRO-CHARACTER-READTABLE
Version 3, 11-Feb-89
Status: Passed (as amended) Jan 89 X3J13

+ GET-SETF-METHOD-ENVIRONMENT
Version 5 13-JUL-87
Status: Passed, 1988?

! HASH-TABLE-ACCESS
Synopsis: Add new accessors for hash-table properties
Version 1, 13-Sep-88 released 8-Oct-88
Version 2, 13 Oct 88, released 16-Mar-89
status: vote 

+ HASH-TABLE-PACKAGE-GENERATORS
Version 7, 8-Dec-88, Released 9-Dec-88
Comments: The test-package-iterator example has the values
 from the generator in  the wrong order.
Status: passed, Jan 89 X3J13

* HASH-TABLE-PRINTED-REPRESENTATION
Version 2, 8-Jun-88
Comments: Use #S(ARRAY ...), #S(HASH-TABLE...), #S(PATHNAME...)?
Status: need new proposal

! HASH-TABLE-SIZE
Version 1, 20-Mar-89, released 21-Mar-89

+ HASH-TABLE-TESTS
Version 2, 8-Dec-88, Released 8 Dec 88
Status: passed Jan 89 X3J13

+ IEEE-ATAN-BRANCH-CUT
Version 2, 11-Jan-89, Released 11-Jan-89
Status: passed, Jan 89 X3J13

* IGNORE-VARIABLE
Synopsis: default (IGNORE IGNORE)
Version 1, 6-Feb-89

+ IMPORT-SETF-SYMBOL-PACKAGE
Version 5 ??-MAY-87
Status: Passed, 1988?

! IN-PACKAGE-FUNCTIONALITY
Version 4, 12-Dec-88, Released 12-Dec-88
Status: tabled
Version 8, 15-Mar-89, Released 15-Mar-89
Status: ready for vote

+ KEYWORD-ARGUMENT-NAME-PACKAGE
8-NOV-87, Version 8
Status: Passed, 1988?

+ LAST-N
12-MAR-88, Version 2
Status: Passed, 1988?

+ LCM-NO-ARGUMENTS
Version 1, 17 Oct 88, Released 8 Dec 88
Status: passed, Jan 89 X3J13

! LISP-PACKAGE-NAME
Synopsis: change LISP to COMMON-LISP to avoid CLtL confusion
Version 1, 22 Dec 88, Released 11-Jan-89
Status: tabled; version 1 still ready for vote

! LISP-SYMBOL-REDEFINITION
Version 5, 22-Nov-88, Released 8 Dec 88
Comments: Don't like (DEFVAR CAR ...) example
	14: Like simpler "Redefining any documented
  definition on a symbol in the LISP package -- such as variables, 
  functions, constants, properties and property-lists, etc -- is
  undefined, except for the explicitly allowed cases (e.g. dynamic
  binding of variables)."
Status: tabled; version 5 still ready for vote

! LOAD-OBJECTS
Synopsis: Provide a way to allow defstruct/defclass objects in compiled files
Version 3, 9-Mar-89, released 16-Mar-89
Comments: How about MAKE-LOAD-FORM-SAVING-SLOTS?
Status: ready for vote w/ name change?

! LOAD-TRUENAME
Synopsis: Make default pathname for LOAD inside LOAD same?
Version 1, 13-Mar-89, Released 16-Mar-89
Status: ready for vote

! LOCALLY-TOP-LEVEL
Version 2, 16-Mar-89, released 17-Mar-89
Status: ready to vote

! LOOP-AND-DISCREPANCY
Version 1, 15-Mar-89, released 16-Mar-89
status: ready for vote

+ MACRO-FUNCTION-ENVIRONMENT
Version 2, 8-JUN-88
Status: Passed, 1988

* MACRO-SPECIAL-FORMS
Synopsis: macros => implementation-dependent special forms doesn't work
Status: *** NEED PROPOSAL SUBMITTED ****

+ MAKE-PACKAGE-USE-DEFAULT
Version 2, 8 Oct 88, Released 12-Dec-88
Version 3, 16-Mar-89
Status: Passed, Jan 89 X3J13 as amended 

! MAKE-STRING-FILL-POINTER
Synopsis: extend MAKE-STRING to take a fill-pointer?
Version 1, 20-Oct-88, released 16-Mar-89
Status: ready for vote

+ MAPPING-DESTRUCTIVE-INTERACTION
Version 2, 09-Jun-88, Released 8 Oct 88
Synopsis: [don't] define interaction of DELETE on MAPCAR'd list.
Status: passed, Jan 89 X3J13

+ NTH-VALUE
Version 4, 8-Dec-88, Released 8 Dec 88
Comment: amended to clarify when index out of range
Version 5, 17-Mar-89
Status: passed, as amended

+ PACKAGE-CLUTTER
Version 6, 12-Dec-88, Released 12-Dec-88
Comments: Accepted, with amendment
Version 7, 17-Mar-89
Status: Passed, Jan 89 X3J13, as amended

+ PACKAGE-DELETION
Version 5, 21 nov 88, Released 8 Dec 88
Comments: Minor glitches? Remove the description of "correctable" error to be signalled and
handled.
Status: passed, Jan 89 X3J13

!+ PACKAGE-FUNCTION-CONSISTENCY
Synopsis: allow strings for package arg everywhere uniformly
Version 2, 12-Jan-89, Released 12-Jan-89
Comment: Accepted MORE-PERMISSIVE with amendments
Version 3, 17-Mar-89, released 17-Mar-89
Status: vote to accept wording as intent of amendment

* PATHNAME-CANONICAL-TYPE
Synopsis: allow canonical :SOURCE-LISP to MAKE-PATHNAME;
	require PATHNAME-TYPE to return same?
Version 1, 07-Jul-88
Comments: only add the :TYPE :SOURCE-LISP, not PATHNAME-CANONICAL-TYPE?
Status: => "pathname" committee?

! PATHNAME-COMPONENT-CASE
Version 2, 22-Mar-89, released 22-Mar-89
Status: vote???

! PATHNAME-COMPONENT-VALUE
Version 1, 20-Mar-89, released 21-Mar-89
Status: vote?

* PATHNAME-LOGICAL
Synopsis: add logical pathnames (pathnames for an imaginary portable
file system, which get translated by site-dependent translations into
physical pathnames on an actual file system)
Status: no proposal yet

* PATHNAME-PRINT-READ
Synopsis: Print pathnames like #P"asdf"?
Version 1, 21-Oct-88
Comments: Numerous, pro, con. Print like #S(pathname ...)?
Status: *** NEED NEW VERSION ***

+ PATHNAME-STREAM
Version 6 14-NOV-87
Status: Passed, 1988?

! PATHNAME-SUBDIRECTORY-LIST
Version 4, 22-Mar-89, released 22-mar-89

+ PATHNAME-SYMBOL
Version 5 5-FEB-88
Status: Passed, 1988?

* PATHNAME-SUBDIRECTORY-LIST
Synopsis: How to deal with subdirectory structures in pathname functions
Version 3, 29-Dec-88
Comments: typos and proposed simplifications
Status: *** NEED NEW VERSION ***

* PATHNAME-SYNTAX-ERROR-TIME
Synopsis: when are errors in pathnames detected?
Version 1, 7-Jul-88
Comments: various
Status: need new version? ==> ERRORS-IN-FILE-CHAPTERS?

+  PATHNAME-UNSPECIFIC-COMPONENT
Synopsis: More extensions to :UNSPECIFIC
Version 1, 29-Dec-88, Released 12-Jan-89
Version 2, 17-Mar-89
Status: Passed, Jan 89 X3j13, as amended

+ PEEK-CHAR-READ-CHAR-ECHO
Version 3, 8-Oct-88, Released 8 Oct 88
Synopsis:  PEEK-CHAR, READ-CHAR on streams made by MAKE-ECHO-STREAM
Status: Passed, Jan 89 X3J13

* PRETTY-PRINT-INTERFACE
Version 3, 15-Mar-89
Synopsis: standardize interface to prettyprinter
Status: Need new version

+ PRINC-CHARACTER
29-APR-87, Version 2
Status: Passed, 1988?

* PRINT-CIRCLE-SHARED
Synopsis: does *PRINT-CIRCLE* cause shared structure to print with #=?
Status: Not submitted yet ** NEED WRITEUP **

+ PRINT-CIRCLE-STRUCTURE
Version 3, 20 Sep 88, Released 8 Oct 88
Comments: Accepted, with amendment
Version 4, 17-Mar-89
Status: Passed, Jan 89 X3J13, as amended

! PROCLAIM-LEXICAL
Version 9, 8-Dec-88, Released 12-Dec-88
Synopsis: add LEXICAL proclaimation
Comments: lengthy mail; amendments at Jan meeting
Status: tabled, vote on version 9 (w/o amendments)

+ PUSH-EVALUATION-ORDER
Version 5, 25-NOV-87
Status: Passed, 1988?

+ RANGE-OF-COUNT-KEYWORDS
Version 3, 9-Oct-88, Released 14-Oct-88
Status: passed, Jan 89 X3J13

+ RANGE-OF-START-AND-END-PARAMETERS
Version 1, 14-Sep-88, Released 7 Oct 88
Status: passed, Jan 89 X3J13

* READ-CASE-SENSITIVITY
Synopsis: Allow readtables to be case sensitive
Comments: use function or keyword?
Status: need new version

* READ-DELIMITED-LIST-EOF
Synopsis: eof in read deliminted list signals an error
Status: awaiting submission

! REAL-NUMBER-TYPE
Synopsis: add REAL = (OR RATIONAL FLOAT) & range
Version 3, 13-Jan-89, released 16-Mar-89
Status: vote?

+ REDUCE-ARGUMENT-EXTRACTION
Version 3 13-FEB-88
Status: Passed, 1988?

! REMF-DESTRUCTION-UNSPECIFIED
Synopsis: Specification of side-effect behavior in CL
Version 4, 29-Nov-88, Released 12-Jan-89
Status: straw vote in favor of this, BarMar will make amendments
Version 6, 17-Mar-89
Status: ready for vote?

+ REQUIRE-PATHNAME-DEFAULTS
Version 6, 9 Dec 88, Released 09 Dec 88
Status: passed, Jan 89 X3j13

+ REST-LIST-ALLOCATION
Version 3, 12-Dec-88, Released 12-Dec-88
Status: proposal MAY-SHARE passed, Jan 89 X3J13

+ RETURN-VALUES-UNSPECIFIED
Version 6, 9 Dec 88, Released  9-Dec-88
Status: passed, Jan 89 X3J13

+ ROOM-DEFAULT-ARGUMENT
Version 1, 12-Sep-88, Released 8 Oct 88
Status: passed, Jan 89 X3J13

! SETF-MULTIPLE-STORE-VARIABLES
Synopsis: Allow multiple "places" in SETF stores
Version 2, 22-Mar-89, released 22-Mar-89
Status: ready for vote?

+ SETF-SUB-METHODS
Version 5, 12-Feb-88, Released 8 Oct 88
Synopsis: careful definition of order inside (SETF (GETF ...) ...) 
Status: passed, Jan 89 X3J13

+ SHADOW-ALREADY-PRESENT
Version 4 10-NOV-87
Status: Passed, 1988?

+ SHARPSIGN-PLUS-MINUS-PACKAGE
Version 3 14-NOV-87
Status: Passed, 1988?

+ SPECIAL-TYPE-SHADOWING
Synopsis: intersection of types when proclaimed special has local type
declaration
Version 1, 4-Nov-88, released 11-Jan-89
Status: passed, Jan 89 X3J13

+ STANDARD-INPUT-INITIAL-BINDING
Version 8, 8 Jul 88, Released 7 Oct 88
Status: passed, Jan 89 X3J13

+ STEP-ENVIRONMENT
Version 3, 20-Jun-88, Released  7 Oct 88
Version 4, 17-Mar-89
status: Passed, Jan 89 X3J13, as amended

+ STREAM-ACCESS
Version 2, 30-Nov-88, Released  9 Dec 88
Status: ADD-TYPES-ACCESSORS passed, Jan 89 X3J13

+ SUBSEQ-OUT-OF-BOUNDS
29-MAR-88 Version 2 
Status: Passed, 1988?

* SUBTYPEP-ENVIRONMENT
Version 1, 2-Jan-89
Status: ** missing writeup ***

+ SUBTYPEP-TOO-VAGUE
Version 4,  7-Oct-88, Released 7 Oct 88
Status: passed, Jan 89 X3J13

+ SYMBOL-MACROLET-DECLARE
Version 2,  9-Dec-88, Released 9 Dec 88
Status: passed, Jan 89 X3J13

!+ SYMBOL-MACROLET-SEMANTICS
Version 5, 30-Nov-88, Released 9 Dec 88
Status: Passed, Jan 89 X3J13
Version 6, 14-Mar-89, released 16-Mar-89
Status: ready for vote

+ TAILP-NIL
Version 5, 9-Dec-88, Released 12-Dec-88
Synopsis: Operation of TAILP given NIL
Status: passed, Jan 89 X3J13

+ TEST-NOT-IF-NOT
Version 3, 1 Dec 88, Released 9 dec 
Version 4, 18-Mar-89
Status: Need new version as amended.

! THE-AMBIGUITY
Version 2, 11-Jan-89, Released 11-Jan-89
Comments: typo, sense wrong
Status: tabled, vote on 2

! TIME-ZONE-NON-INTEGER
Version 1, 13-Mar-89, Released 16-Mar-89
Status: ready for vote

+* TYPE-OF-UNDERCONSTRAINED
Version 3, 12-Dec-88, Released 12 Dec 88
Comments: Accepted, with amendments
Version 5, 16-Mar-89
Comments: constraints wrong
Status: ** NEED NEW VERSION ***

! UNDEFINED-VARIABLES-AND-FUNCTIONS
Synopsis: What happens on an undefined function call, unbound variable ref?
Version 1, 29-Nov-88, Released 11-Jan-89
Comments: Lumping SLOT-UNBOUND in with unbound special variables was a mistake,
           as SLOT-UNBOUND is an extension mechanism, not only a safety checking
           mechanism.  Also there were some wording problems.  Gabriel and Gregor
           are to submit a revised proposal.
		No version arrived.
Status: vote on 1?

+ UNREAD-CHAR-AFTER-PEEK-CHAR
Version 2, 2-Dec-88, Released 12-Dec-88
Status: passed, Jan 89 X3J13

+ VARIABLE-LIST-ASYMMETRY
Version 3, 08-Oct-88, Released 9 Dec 88
Status: passed, Jan 89 X3J13

+ WITH-OUTPUT-TO-STRING-APPEND-STYLE
Version 5, 7-JUN-88 
Status: Passed, 1988?

! WITH-OPEN-FILE-DOES-NOT-EXIST
Version 1, 17-Mar-89
Status: ready?

∂23-Mar-89  1657	X3J13-mailer 	cl-compiler issue status as of Mar 23    
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 23 Mar 89  16:23:32 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA18840; Thu, 23 Mar 89 16:53:11 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA12850; Thu, 23 Mar 89 16:53:08 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903232353.AA12850@defun.utah.edu>
Date: Thu, 23 Mar 89 16:53:06 MST
Subject: cl-compiler issue status as of Mar 23
To: x3j13@sail.stanford.edu

Here is the current list of active cl-compiler issues.  I have mailed
out revised versions of most of the issues where we got some specific
comments on the previous version, and I've noted other comments below.

There will be hardcopies of all of the latest and greatest writeups
available at the meeting.  I'm not anticipating that we will be
producing another round of revisions before then, so if you want
something changed, please be prepared to present an amendment at the
meeting.


CLOS-MACRO-COMPILATION (version 3)
    Clarify compile-time behavior of CLOS defining macros.
      Proposal MINIMAL
      Proposal NOT-SO-MINIMAL
    [New version distributed in response to comments.]

COMPILE-ENVIRONMENT-CONSISTENCY (version 5)
    What kinds of things can/must the compiler "wire in" to the code
    it compiles?
      Proposal CLARIFY
    [New version distributed in response to comments.]

COMPILE-FILE-SYMBOL-HANDLING (version 2)
    How does COMPILE-FILE tell LOAD what package to put symbols in?
      Proposal CURRENT-PACKAGE
      Proposal HOME-PACKAGE
      Proposal REQUIRE-CONSISTENCY
    [Some people want to leave this unspecified.]

COMPILED-FUNCTION-REQUIREMENTS (version 5)
    What does the COMPILED-FUNCTION type imply?  Do COMPILE and 
    COMPILE-FILE construct COMPILED-FUNCTIONs?
      Proposal TIGHTEN
      Proposal TIGHTEN-COMPILE
      Proposal FLUSH
    [New version distributed in response to comments.]

COMPILER-DIAGNOSTICS (version 10)
    Clarify status and handling of errors and warnings signalled during 
    compilation.
      Proposal USE-HANDLER
    [New version distributed in response to comments.]

COMPILER-LET-CONFUSION (version 8)
    The description of COMPILER-LET in CLtL is broken -- should we fix
    it or eliminate it entirely?
      Proposal REPAIR
      Proposal ELIMINATE
    [New version distributed in response to comments.]

COMPILER-VERBOSITY (version 6)
    Mechanisms for controlling progress messages issued by the compiler.
      Proposal LIKE-LOAD
 
CONSTANT-CIRCULAR-COMPILATION (version 8)
    Must circular or recursive objects be compiled correctly?  Must the
    compiler preserve sharing of substructures?
      Proposal NO
      Proposal PRESERVE-SHARING-ONLY
      Proposal YES
    [New version distributed in response to comments.
     Expect amendment to change error terminology.]

CONSTANT-COLLAPSING (version 6)
    Should the compiler be allowed to "collapse" or coalesce constants
    that satisfy a more general equivalence relationship than EQUAL?
      Proposal GENERALIZE
    [New version distributed in response to comments.]

CONSTANT-COMPILABLE-TYPES (version 9)
    What types of objects can appear as quoted or self-evaluating constants
    in compiled code?
      Proposal SPECIFY
    [New version distributed in response to comments.]

CONSTANT-FUNCTION-COMPILATION (version 1)
    What do we do about quoted function constants?
      Proposal NO
    [This is a new issue, split off from CONSTANT-COMPILABLE-TYPES.  We
     are willing to consider alternate proposals.]
    
DEFCONSTANT-NOT-WIRED (**DRAFT** version 6)
    How do you declare a variable to be constant without giving the
    compiler permission to make assumptions about its value?
    [None of the proposals are ready to be voted on.  This issue
     is being distributed only for informational purposes.]

DEFINE-OPTIMIZER (version 6)
    Provide a macro-like way of specifying source-level optimizations
    on function calls.
      Proposal NEW-FACILITY
    [New version distributed in response to comments.]

DEFINING-MACROS-NON-TOP-LEVEL (version 9)
    Are defining macros such as DEFUN meaningful in non-top-level locations?
      Proposal ALLOW
    [New version distributed in response to comments.]

EVAL-WHEN-NON-TOP-LEVEL (version 7)
    What does EVAL-WHEN mean when it appears in non-top-level locations?
      Proposal GENERALIZE-EVAL
      Proposal GENERALIZE-EVAL-NEW-KEYWORDS
    [New version distributed in response to comments.]

LOAD-TIME-EVAL (version 11)
    Add a new special form, LOAD-TIME-VALUE.
      Proposal R**2-NEW-SPECIAL-FORM
      Proposal R**3-NEW-SPECIAL-FORM
    [Proposal R**2-NEW-SPECIAL-FORM was approved at the January meeting,
     but some additional suggestions were made after the meeting.]

MACRO-CACHING (version 2)
    Is it legitimate to cache macro expansions?
      Proposal DISALLOW
      Proposal RESTRICT
    [Moon suggested the presentation could be simplified.]

MACRO-ENVIRONMENT-EXTENT (**DRAFT** version 3)
    Do environment objects received as the &ENVIRONMENT argument to a 
    macro have dynamic or indefinite extent?
      Proposal INDEFINITE
      Proposal DYNAMIC
      Proposal DYNAMIC-WITH-COPIER
    [Barmar wants the copier function renamed (to what?)]

PROCLAIM-ETC-IN-COMPILE-FILE (**DRAFT** version 4)
    Are top-level calls to PROCLAIM handled specially by the compiler?
      Proposal YES
      Proposal NO
      Proposal NEW-MACRO
    [New name for DEFPROCLAIM?]

QUOTE-SEMANTICS (version 3) (replaces QUOTE-MAY-COPY)
    May COMPILE and EVAL construct equivalent copies of quoted or 
    self-evaluating constants, or must constants share structure with
    the source code for the program?  Do the constraints on what objects
    are valid constants also apply to COMPILE and EVAL, or only to
    COMPILE-FILE?
      Proposal NO-COPYING
      Proposal COPYING-ALLOWED-BUT-NO-CONSTRAINTS
      Proposal SAME-AS-COMPILE-FILE
    [New version distributed in response to comments.]

SAFE-CODE (version 1)
    What does the term "safe code" mean?
      Proposal SAFETY-3
    [This issue has been withdrawn.]

SYNTACTIC-ENVIRONMENT-ACCESS (version 6)
    Provide accessors and constructors for lexical environment objects.
      Proposal SMALL
    [New version distributed in response to comments.]

WITH-COMPILATION-UNIT (version 3)
    Provide a way to compile a group of files as a unit for the purposes
    of error messages.
      Proposal NEW-MACRO
    [There have been complaints that the proposal is not ready to be
     voted on.]







-------

∂23-Mar-89  1656	X3J13-mailer 	Issue: PATHNAME-COMPONENT-VALUE (version 1)   
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 23 Mar 89  15:52:13 PST
Received: from pitney-bowes ([192.9.200.50]) by heavens-gate.lucid.com id AA03552g; Thu, 23 Mar 89 12:36:58 PST
Received: by pitney-bowes id AA26463g; Thu, 23 Mar 89 12:35:22 PST
Date: Thu, 23 Mar 89 12:35:22 PST
From: Jim McDonald <jlm@lucid.com>
Message-Id: <8903232035.AA26463@pitney-bowes>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
Cc: X3J13@SAIL.STANFORD.EDU
In-Reply-To: David A. Moon's message of Tue, 21 Mar 89 17:52 EST <19890321225242.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: Issue: PATHNAME-COMPONENT-VALUE (version 1)

PATHNAME-COMPONENT-VALUE:SPECIFY seems seriously flawed to me.  I give
some reasons, a sktech of a strawman alternative, and some options to
consider.  Pardon the length, but the issue is one of the messiest that
CL must deal with.  If you're really pressed, search for "given all".

My particular concern is that by restricting pathname-names, for
example, to be strings, PATHNAME-COMPONENT-VALUE:SPECIFY hides the
semantics associated with a pathname behind host-specific string
parsing rules.  ("Structured" names are forbidden.)  My comments will
refer to pathname-names, but similar arguments should apply for
pathname-types and elements of directory lists.

Part of the rationale says:

  Removing "structured" names should improve portability without causing
  any harm, assuming no implementation uses structured names.  This will
  improve portability by allowing programs to do string manipulation on
  names, although such programs still have to be careful since the valid
  characters and maximum length of a name are implementation-dependent.

But I fail to see how string manipulation functions are particularly
useful or intuitive when porting the un*x c-shell wildcard name
"/foo/a?b.lisp" into an MVS pathname, where there is no system support
for single-character wildcards.  I would rather specify something
like:

   (MAKE-PATHNAME :DIRECTORY *source-dir*
                  :NAME      '("a" :WILD-CHARACTER "b") 
                  :EXTENSION "lisp")

and let CL handle the wildcard problem if the OS doesn't.

Also note that the "host" parsing rules may be something as specific
as a shell convention.  E.e., un*x filesystems do not treat "*" at 
all specially--that is done by the shells.  Only a kind of peer 
pressure keeps the shells and other utilities fairly consistent on a
given machine.

In spite of the paragraph quoted above from the rationale, I assume
the best motivation for hiding the semantics is to be able to defer
all such semantic questions to the host, to avoid any need to query
the host during normal pathname manipulations.  I.e., when a user
types "a$b" for host foo, lisp don't need to query foo to discover
that this is a wildcard template or means burn after reading.  (Don't
laugh--the "3" in "FOO LISP A3" for CMS means erase this file as soon
as the first reference is closed, as opposed to "FOO LISP A1" which 
means treat this as a normal file, or "FOO LISP A7" which is illegal.)

Overall, I see three generic problems:

  (1)  To determine if a given pathname-name (e.g. "a$b") is a specific
       filename or a template, one needs to invoke some as-yet
       unspecified oracle.  Something like the proposal
       PATHNAME-EXTENSIONS would be needed to address this issue.

  (2)  To portably make a template to select a given set of filenames,
       one needs to consult an unspecified inverse oracle.  

       >> I've seen no proposal that addresses this problem. <<

       E.g., consider the problem of making a template that will match
       all filenames on a given directory starting with "a" and ending
       with "b".  How would I write this??

       Or consider the problem of finding all files that match "*foo*"
       (using Unix csh conventions), but not "*.lisp".  Under the
       given proposal, one is forced to use the DIRECTORY function to
       get truenames for all the "*.lisp" files before doing the
       set-difference.  This seems very clumsy and wasteful when
       compared to what DIRECTORY could accomplish if it understood
       pathnames containing regular expressions. 

       Also note that some operating systems (e.g. MVS) support the
       notion of the "*" wildcard convention (wild string), but not
       "?" (wild character).  So the proposal mandates that it must be
       impossible to portably create a pathname template for names of
       three characters starting with "a" and ending with "b". 

  (3)  OS oracles such as those proposed by PATHNAME-EXTENSIONS cannot
       hope to address all novel or idiosyncratic features of
       file-systems, except in the very weak sense of saying "here be
       dragons".  More informative oracles would be needed for
       portability, so over time we must be prepared to augment the
       standard or ports must write ad hoc oracles for things like
       "A3" on CMS.  This is only vaguely addressed through the
       proposals about legal extensions to Common Lisp. 

An alternative scheme (admittedly not perfect) would be to standardize
an internal format for things like wildcard templates, e.g. 
("a" :WILD-STRING "b").  This addresses the three problems as follows: 

  (1)  The first problem partially goes away--e.g., "a$b" could be
       treated unambiguously as a three-character filename, even for
       hosts where shells, etc. tend to treat "$" specially.
       Templates would be required to be non-atomic objects, perhaps
       lists starting with :WILD.  (In effect, the oracle at this
       level has been reduced to simple standardized rules on obvious
       lisp data formats.) 

       Unfortunately, the problem has been pushed to another level,
       since users are presumably typing filenames according to host-
       specific conventions which they expect to be honored.  Even if
       the internal representation becomes largely host-independant,
       parse-namestring may need to consult the same oracles mentioned
       above to be able to internalize correctly.  This could even be
       pessimal in putting all of the semantic burden (hence perhaps
       file-system queries) up front when it might otherwise be
       avoided.  In general though, there can be CL code to emulate
       most of the parsing that would be done by the filesystem, and
       there could be an escape such as (:UNPARSED "a$b"), to allow
       parsing to be deferred until necessary.  

       On the whole, I think something like this alternative scheme
       would win on this point. 
     
  (2)  The second problem goes away (it was the original motivation
       for this message).  E.g., the rules for making a wildcard are
       standardized and portable.  (Of course, each implementor then
       needs to interpret ("a" :WILD-STRING "b") appropriately, which
       might involve the creation of a string like "a$b".  But
       implementors are trained to deal with such details.) 

  (3)  The third problem comes back with a vengeance, since nothing
       would be passed through "as is", and thus novel features by
       definition would be prohibited.  This could be addressed by
       adding an escape that passes things through to the OS for
       semantic parsing without CL attempting to understand them.  How
       users would indicate this option is problematic.

Given all of the above, I think a more flexible proposal for pathnames
would allow the name field (for example) to be structured as at least
any of the following: 

  "a*b"                   -- a 3-character filename, or
  (:EXPLICIT "a*b")       -- a 3-character filename

  ("a" :WILD-STRING "b")  -- a template for filenames string with "a"
                             and ending with "b"

  (:UNPARSED "a*b")       -- a filename or template that may require
                             an OS request to disambiguate (when
                             parsed, this should yield a standard CL
                             format)

  (:UNINTERPRETED "a*b")  -- a filename or template that CL will not
                             attempt to understand (if used 
                             inappropriately, the consequences are 
                             undefined)

It should be a separate issue which of these (PARSE-NAMESTRING "a*b")
would produce.

PATHNAME-COMPONENT-VALUE:SPECIFY seems to give "a*b" the semantics of 
:UNINTERPRETED and forbid all other options.  Personally, I would
prefer to give "a*b" the semantics of :EXPLICIT and allow at least 
these four options.

The rules for parse-namestring require more thought than I can afford
right now, but I hope this suffices to show that the stated proposal
is, unfortunately, far more problematic than advertized.

   jlm


∂23-Mar-89  2100	X3J13-mailer 	Issue: GENSYM-NAME-STICKINESS (Version 3)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 89  21:00:01 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 564017; Thu 23-Mar-89 17:34:54 EST
Date: Thu, 23 Mar 89 17:34 EST
From: CL-Cleanup@SAIL.Stanford.EDU
Sender: KMP@STONY-BROOK.SCRC.Symbolics.COM
Reply-To: CL-Cleanup@SAIL.Stanford.EDU
Subject: Issue: GENSYM-NAME-STICKINESS (Version 3)
To: X3J13@SAIL.Stanford.EDU
Message-ID: <890323173428.2.KMP@BOBOLINK.SCRC.Symbolics.COM>

Issue:        GENSYM-NAME-STICKINESS
Forum:	      Cleanup
References:   GENSYM (p169)
Category:     CHANGE
Edit history: 14-Feb-89, Version 1 by Pitman
	      15-Mar-89, Version 2 by Steele (add GENSYM-COUNTER function)
	      20-Mar-89, Version 3 by Pitman (make it a variable)

Problem Description:

  Many people avoid use of the argument to GENSYM because the argument
  is `sticky' and such stickiness can lead to confusion. The problem is
  that if any application (usually a macro) uses the gensym argument at
  all, then all applications are forced to. If they do not, they risk
  finding that the `helpful' argument supplied in some previous call will
  be harmful to them.

Proposal (GENSYM-NAME-STICKINESS:LIKE-TEFLON)

  Define that if an optional argument [either a string or a number] is
  given to GENSYM, it does NOT have a side-effect on GENSYM's internal state.

  Introduce a new variable, *GENSYM-COUNTER*, which holds the state of
  the gensym counter. That is, the next symbol generated by GENSYM will
  be number n.  The initial value of this variable is not defined, but
  must always be a non-negative integer. This variable may be either 
  assigned or bound by users at any time, but always to a non-negative
  integer.

  Deprecate the use of a numeric argument to GENSYM.

Rationale:

  Conscientious programmers are forced now to write their own GENSYM
  lookalikes because they know the system's GENSYM has an invasive
  effect. This defeats the primary intended function of GENSYM, which
  is to satisfy the most common idiomatic use of MAKE-SYMBOL.

  The stickiness of the GENSYM prefix was an attempt to be gratuitously
  compatible with Maclisp, at the expense of good programming pratice.

  Users who need the old behavior of GENSYM can trivially implement
  that behavior using MAKE-SYMBOL.

  Occasionally you want to reset the GENSYM counter so that, for example,
  you can get the compiler to generate the same symbol names again
  (good for comparing results to see what really changed).

Test Case:

  ;; #1: Test stickiness of name part.
  (CHAR-EQUAL (CHAR (SYMBOL-NAME (SECOND (LIST (GENSYM "A") (GENSYM)))) 0)
	      #\G)
  => NIL ;under CLtL
  => T   ;under this proposal

  ;; #2: Test stickiness of number part.
  (= (PARSE-INTEGER (PROGN (GENSYM 6789) (STRING (GENSYM "G"))) :START 1)
     6790)
  => T   ;under CLtL
  => NIL ;under this proposal (except when *gensym-counter* happens to align)

  ;; #3: Illustrate use of new variable.
  (STRING= (SYMBOL-NAME (LET ((*GENSYM-COUNTER* 43)) (GENSYM "FOO")))
           "FOO43")
  => T   ;under this proposal (not meaningful previously)

Current Practice:

  Symbolics Cloe and Genera are compatible with CLtL, so this would be an
  incompatible change.

Cost to Implementors:

  Very small.

  If any implementations currently use a more compact representation for
  the internal state of GENSYM than a variable holding a string and a
  separate variable holding an integer, they might be forced to change.
  Even then, the change would proabably still be quite small.

Cost to Users:

  Most uses of GENSYM do not depend on the stickiness of the name, so the
  change would be compatible. In some cases, the change would be an
  improvement. Even in the worst case where someone depends on stickiness,
  it's extremely straightforward to write the couple of lines of code to
  produce an application based on MAKE-SYMBOL that is at least as flexible
  as GENSYM, and often moreso.

Cost of Non-Adoption:

  Good programmers would avoid using the argument to GENSYM (or using 
  GENSYM altogether) in many situations where they ought not have to.

Benefits:

  Gensyms which appear to convey information through their name would not
  accidentally pop out and cause confusion in places where they oughtn't.

  Making the gensym counter visible as a variable means that people will
  be able to bind the gensym counter locally when they don't want to affect
  the global counter.

Aesthetics:

  Unnecessary global state changes are hard to reason about. This would 
  be a small simplification.

Discussion:

  Pitman claims to have written a non-sticky GENSYM function for nearly
  every one of the dozen or so large systems that he's written or worked
  on in the last decade in order to get around the stated problem.
  Others have suggested similar experience.

  Pitman and Steele support LIKE-TEFLON.

∂23-Mar-89  2059	X3J13-mailer 	**DRAFT** Issue: PATHNAME-PRINT-READ (Version 1)   
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 89  20:59:42 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 563865; 23 Mar 89 15:36:42 EST
Date: Thu, 23 Mar 89 15:36 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** Issue: PATHNAME-PRINT-READ (Version 1)
To: X3J13@SAIL.Stanford.EDU
Message-ID: <890323153624.3.KMP@BOBOLINK.SCRC.Symbolics.COM>

	>>> PLEASE DO -NOT- REPLY TO THIS ISSUE <<<

Ponder it and come prepared to discuss it at the meeting.

See summary of Cleanup discussion at end.
 -kmp

-----
Issue:        PATHNAME-PRINT-READ
References:   File System Interface (pp409-427)
Category:     CHANGE/ADDITION
Edit history: 21-Oct-88, Version 1 by Pitman
Status:	      For Internal Discussion

Problem Description:

  Although pathnames are required to print re-readably, there is no
  standardized representation for pathnames and so no standardized
  way in which they should print.

  Further, it is common in programs to want pathnames to print in
  their file-system specific format.

Proposal (PATHNAME-PRINT-READ:SHARPSIGN-P):

  Define the reader syntax #P"..." to be equivalent to 
  #.(PARSE-NAMESTRING "...").

  Define that when *PRINT-ESCAPE* is T, the syntax #P"..." is
  how a pathname should be printed by WRITE (and hence by PRIN1,
  PRINT, etc.). The "..." is the namestring representation of the
  pathname.

  Define that when *PRINT-ESCAPE* is NIL, WRITE writes a pathname
  object P by writing (NAMESTRING p) instead.

Test Case:

  (PARSE-NAMESTRING "foo.lisp")
  => #P"foo.lisp"

  (FORMAT NIL "Written to ~A." #P"foo.bin")
  => "Written to foo.bin."

  (TYPEP #P"foo.bin" 'PATHNAME)
  => T

Rationale:

  This satisfies the stated goals.

  [For :ESCAPE T] It will not be possible to make the printed
  pathname printed representation totally portable because of
  variations in file systems, but for different Common Lisp
  implementations on the same file system, or for Common Lisp
  systems running on file systems having compatible syntax,
  portability would be improved by this specification.

  Also, some implementations (eg, Symbolics Genera) use
  specialized representations for pathnames on different file
  systems. Eg, an MSDOS pathname is of type MSDOS-PATHNAME,
  not just type PATHNAME. #S(PATHNAME ...) is not only more
  verbose than necessary but might be misleading to some users
  because the object created will not have a TYPE-OF PATHNAME.

  [For :ESCAPE NIL] Printing the namestring of a pathname is
  a common operation and it is convenient to have a shorthand
  for doing it. Further, some implementations may be able to
  optimize the presentation of a pathname in this mode by
  printing it without actually consing the string.

Current Practice:

  Symbolics Genera implements the proposed behavior.

Cost to Implementors:

  Fairly minor changes to the readtable and the printer.

Cost to Users:

  Users who now use the non-portable syntax #S(...) in order
  to enter literal pathnames might have to change. [However,
  implementations would be free to continue to support this
  read syntax for compatibility.]

Cost of Non-Adoption:

  Portability of code and data involving pathnames within a
  given file system (or between suitably similar file systems)
  would be hampered needlessly.

Benefits:

  The cost of non-adoption would be avoided.

Aesthetics:

  The #P syntax is pretty and hides unimportant details.

Discussion:

  Pitman supports this change.

-----
Summary of discussion on CL-Cleanup:

 EB noted that Lucid CL implements the proposed behavior and that there
  is cost to users who define their own #P read macro. He weakly supports
  the proposal but wishes someone had pursued a `generic pathnames' proposal.

 Pierson noted that KCL uses #"...", but that this collides with proposed
  syntax for Dick Waters' pretty printer. He also thinks #P is better
  because it is already more widely used for that purpose.

 Masinter noted that Envos Medley prints pathnames with the syntax
  #.(pathname "asdf"), which he thinks is not as pretty as #P"asdf"
  but currently more portable.

 KMP and JonL raised the issues that #. has the disadvantage that it must
  be parsed by the full Lisp engine, while #P can be parsed by something
  simpler.  Permitting #. leaves a gaping hole for trojan horses, and
  also requires the presence of the evaluator in a delivery system.

 MLY, GSB, Peirson, and IIM argued for not using up an extra dispatch
 character.

 MLY suggested #S(PATHNAME namestring [optional-host]).

 IIM noted they use #.(PATHNAME namestring host) because different file
  systems have different parsing conventions. 

∂23-Mar-89  2059	X3J13-mailer 	**DRAFT** Issue: PATHNAME-SYNTAX-ERROR-TIME (Version 1) 
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 23 Mar 89  20:59:16 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 563835; Thu 23-Mar-89 15:19:53 EST
Date: Thu, 23 Mar 89 15:19 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** Issue: PATHNAME-SYNTAX-ERROR-TIME (Version 1)
To: X3J13@SAIL.Stanford.EDU
Message-ID: <890323151934.2.KMP@BOBOLINK.SCRC.Symbolics.COM>

	>>> PLEASE DO -NOT- REPLY TO THIS ISSUE <<<

Ponder it and bring your comments to the meeting.

See summary of CL-Cleanup discussion at end.
 -kmp

-----
Issue:        PATHNAME-SYNTAX-ERROR-TIME
References:   File System Interface (pp409-427)
Category:     CLARIFICATION
Edit history: 07-Jul-88, Version 1 by Pitman
Status:	      For Internal Discussion

Problem Description:

  There exist conceivable pathnames for which there is no valid mapping in a
  particular implementation. CLtL is not clear about the time at which this
  error might be detected.

  For example, on file systems which constrain pathname-types to be three
  letters or fewer, the type "LISP" is not valid. The question arises: when
  is this error detected?

  In some implementations, the error might be detected while forming the
  pathname. That is, (MAKE-PATHNAME :TYPE "LISP") signals an error.

  In some implementations, the error might be detected while forming the
  namestring. That is, (MAKE-PATHNAME :TYPE "LISP") succeeds, but
  (NAMESTRING (MAKE-PATHNAME :TYPE "LISP")) signals an error.

  In some implementations, validity checking might be done only by the host
  operating system, so Lisp does not detect the error unless the operating
  system complains. For example, (MAKE-PATHNAME :TYPE "LISP") succeeds,
  and even (NAMESTRING (MAKE-PATHNAME :TYPE "LISP")) constructs a plausible
  looking pathname, but (OPEN (NAMESTRING (MAKE-PATHNAME :TYPE "LISP"))) fails.

  In some implementations, Lisp might make `friendly' corrections to the
  pathname in order to form a namestring. For example,
  (MAKE-PATHNAME :TYPE "LISP") might succeed, but 
  (NAMESTRING (MAKE-PATHNAME :TYPE "LISP")) might produce a namestring with
  an extension such as ".LIS" or ".LSP".

  Similar issues might come up in file systems which don't allow wildcard
  pathnames. Is :WILD allowed in a name or type slot and then disallowed
  upon coercion to a pathname, or is :WILD complained about "up front"?

  This phenomenon is a barrier to portability because if a program is
  debugged in an implementation that does, for example, NAMESTRING-time
  error checking, the programmer may be lulled into an expectation that
  it is acceptable to construct and manipulate invalid pathnames as long
  as the problem is caught before an attempt to call NAMESTRING is
  attempted. On the other hand, another programmer may debug his code in
  a Lisp which does early error checking of syntax and may assume that 
  he is home free if the pathname gets constructed correctly.

Proposal (PATHNAME-SYNTAX-ERROR-TIME:PATHNAME-CREATION):

  Clarify that operations such as MAKE-PATHNAME and MERGE-PATHNMES which
  construct new pathnames do plausibility checking of their arguments
  and signal an error rather than construct a pathname for which NAMESTRING
  would not produce a valid pathname.

  Rationale:

    This would identify clearly to the programmer where he should expect an
    error to be signalled for a pathname.

    This would mean that fully constructed pathnames could reliably
    be converted to namestrings.

  Cost to Implementors:
  
    Some implementors, especially those which rely on the operating system
    to be the sole authority on pathname syntax, might have to introduce
    some new syntax-checking facilities.

    Implementations where this error checking is done later would have to be
    changed both to do it earlier, and to not make the unwarranted assumption
    that pathnames with no valid namestring representation are constructable.

  Cost to Users:

    The ability to represent non-viable pathnames for the purpose of merging
    would be lost. This feature was not portably available, but was available
    in some operating systems.

    Some code which expected an error, but expected it at a different time
    would have to be changed.

Proposal (PATHNAME-SYNTAX-ERROR-TIME:NAMESTRING-COERCION):

  Clarify that it was valid to create a pathname which could not be
  converted to a namestring. Require NAMESTRING (and related functions,
  such as ENOUGH-NAMESTRING or any internal functions that might be used
  in place of NAMESTRING by functions like OPEN and PROBE-FILE) to signal
  an error for pathnames which do not represent valid filenames in the
  designated file system.

  Rationale:

    This would identify clearly to the programmer where he should expect an
    error to be signalled for a pathname.

    This would allow the construction of pathnames for the sole purpose of
    merging without causing what might seem to some as gratuitous errors.

  Cost to Implementors:
  
    Implementors who rely on the operating system to be the sole authority
    on pathname syntax, might have to introduce some new syntax-checking
    facilities.

    Implementations where this error checking is done earlier would have to
    be changed both to do it later, and to not make the unwarranted
    assumption that any pathname has a valid namestring representation.

  Cost to Users:

    Early error checking of faulty pathnames would be lost.

    Some code which expected an error, but expected it at a different time
    would have to be changed.

  Benefits:
  
    Macsyma, for example, has encountered a need for "hostless" pathnames
    (in merging). The concept makes no sense if every pathname must have
    a namestring, because a pathname with no host cannot have a namestring.
    However, if it's NAMESTRING's responsibility to signal an error, then
    hostless pathnames are still useful for merging. Consider:
	(MERGE-PATHNAMES (MAKE-PATHNAME :NAME "FRED") MARY)
    This will override both the NAME and the HOST field of MARY because you
    must currently have a host in every pathname. But if MAKE-PATHNAME did
    not force the host, or if one could explicitly say :HOST NIL, then
    such pathnames would be considerably more useful for merging.

Proposal (PATHNAME-SYNTAX-ERROR-TIME:EXPLICITLY-VAGUE):

  Clarify that we were unable to reach agreement on this issue and that
  the time at which this error detection occurs is not well-specified.

  Advise the editorial group to warn users clearly about this known source
  of program portability problems.

  Rationale:

    This implements the status quo.

  Cost to Implementors:
  
    None.

  Cost to Users:

    No existing code must be modified, but there is an ongoing cost
    associated with providing error checking at multiple points in a
    program because implementations disagree as to where an error
    might be signalled. In some cases, the effects of having to handle
    this in multiple places may cause unpleasant modularity violations.

Test Case:

  See problem description.

Current Practice:

  Symbolics Genera signals an error at pathname construction time if a
  pathname will be invalid. Once a pathname is successfully constructed,
  it can generally be assumed that NAMESTRING will always succeed.

Aesthetics:

  Making this more well-defined would cause a definite aesthetic
  improvement to some programs.

Discussion:

  Pitman prefers PATHNAME-SYNTAX-ERROR-TIME:NAMESTRING-COERCION but
  believes that anything is an improvement over ...:EXPLICITLY-VAGUE.

  CL pathname functions were not adequate for use in Macsyma because
  they did not adequately represent to-be-merged-only pathnames (a
  feature used very extensively in Macsyma), because errors could be
  signalled at radically different times. To get around this, Pitman
  had to create a data structure in Macsyma called an MPATHNAME which
  was only trivially different than a PATHNAME but which made it
  possible to deal portably with this issue of when errors occurred
  and what kinds of errors occured. Unfortunately, since none of the
  CL functions worked on MPATHNAMEs, a whole series of functions,
  also only trivially different, had to be created: MAKE-MPATHNAME,
  MNAMESTRING, MERGE-MPATHNAMES, MPATHNAME-NAME, MPATHNAME-TYPE, 
  MOPEN, WITH-MOPEN-FILE, etc.

------
Summary of CL-Cleanup discussion:

Most of the mail was endorsements for option PATHNAME-CREATION.
Sandra brought up a tangential issue about truenames that eventually
became a separate issue.

I think I'm the only person pushing NAMESTRING-COERCION. I strongly
believe it is the right thing, and that PATHNAME-CREATION is suboptimal,
based on problems that have struck me with existing CL pathname system.
However, even PATHNAME-CREATION would be an improvement from a
portability standpoint and I am probably not going to push it because
there are compatibility issues on the side of PATHNAME-CREATION (many
implementations do this already), and because there are more important
issues for us to spend time on at the meeting.

[Please try to come prepared to vote yes on one or both of
 PATHNAME-CREATION or NAMESTRING-COERCION so we don't have to fall back
 on EXPLICITLY-VAGUE, which is a total loss for program portability.
 -kmp]

∂24-Mar-89  0824	X3J13-mailer 	Re: 20 March cs proposal  
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 24 Mar 89  08:24:29 PST
Received: from defun.utah.edu by cs.utah.edu (5.61/utah-2.1-cs)
	id AA02507; Fri, 24 Mar 89 09:24:27 -0700
Received: by defun.utah.edu (5.61/utah-2.0-leaf)
	id AA13370; Fri, 24 Mar 89 09:24:24 -0700
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8903241624.AA13370@defun.utah.edu>
Date: Fri, 24 Mar 89 09:24:23 MST
Subject: Re: 20 March cs proposal
To: Thom Linden <baggins@IBM.com>
Cc: Common Lisp mailing <x3j13@sail.stanford.edu>
In-Reply-To: Thom Linden <baggins@IBM.com>, Wed, 22 Mar 89 15:01:01 PST

The organization of this document is much improved -- I found the
presentation to be much more coherent (although some of the proposals
still seem to be grouped in the wrong place) and was able to make some
connections between the various parts that I hadn't been able to make
before.  However, there also seemed to be a few things that got lost
between the last version and this one.

Page 4: I find the use of the word "control" to describe non-graphic
characters confusing (it has too many other connotations).  CLtL used
"non-graphic"; let's stick with that term.

Page 6: Something that appears to have gotten lost from the previous
version is removing the statement from CLtL that characters with
non-zero bits and font are not STANDARD-CHARs.  As I understand your
proposals, you want STANDARD-CHARs to be STANDARD-CHARs regardless of
whether or not they have any attributes associated with them, right?

Page 7: "Redefine STRING-CHAR".  Why not just remove/deprecate it
entirely?  STRING-CHAR used to identify what characters could be
stored in a string; the new set of proposals has defined STRING so
that any character can be stored in one.  Also, it seems like this
item doesn't really belong in this particular proposal (since it has
little to do with removing bits and fonts).

Page 12: "it is an error to insert an extended character into a base
string" => "the consequences are undefined"?

Page 14, section 2.4: Unless and until there is an ISO standard for
character registries, I think it would be silly to include the
proposals in this section in the standard.  For example, implementors
would have to arbitrarily define their own repertoires and labels for
the characters they support, which would almost certainly be
incompatible with any standard that is eventually adopted as well as
with the repertoires defined by other implementations.  This would
make it impossible to use the functions proposed in this section
portably.

Page 18: In proposal 2.5.1, what is the interpretation of the "name"
argument?  Must it follow the same rules as described for the 
:EXTERNAL-CODE option to OPEN below?  Is a list valid?  How about
the keyword :DEFAULT?

Page 18: The material in proposals 2.5.1 and 2.5.2 can not be used
portably, for two reasons.  First, there are no standard names for
coded character sets being proposed here.  Second, even if we
standardized names, implementations are not being required to support
any particular coded character sets.  Therefore I believe this
functionality has no place in the standard.  I wouldn't have any
objection to simply stating that OPEN can be extended to accept
additional keyword arguments that are treated in an
implementation-specific manner, or even saying that it takes an
:EXTERNAL-CODE keyword that is treated in an implementation-specific
manner, but let's at least be honest about the nonportability and
not mislead users into thinking these things are more portable than
they really are.

Page 19, Proposal 2.5.4: Given the discussion on page 11, it seems
like the right default :ELEMENT-TYPE is BASE-CHARACTER.  But I won't
quibble about it.

Page 20, STRING-ENCODED-LENGTH: In the previous version of the
writeup, there was some verbiage (on page 14) that said that this
function takes a string or character object as its required argument.
This has been lost.  Is this function now intended to take *any*
object as an argument and determine how much room its printed
representation will take?

I still think this function is useless as currently defined.
"Implementation defined units" is just too vague.  I could probably be
convinced to vote for adding such a function if it were tied to the
FILE-POSITION function -- for example, define STRING-ENCODED-LENGTH as
the difference between what (FILE-POSITION output-stream) would be
after writing the string and its current value.  It might also be
more appropriate to name it FILE-STRING-LENGTH or something like that
and rearrange the arguments to make it parallel FILE-POSITION and
FILE-LENGTH.

Page 20, Proposal 2.6.2: Why prohibit control (non-graphic) characters
from appearing in a symbol's print name?  The context in which the
sentence this replaces appears has to do with how the reader deals
with the case of symbol names, not with restricting what characters
are valid in the print name.

Page 20, Proposal 2.6.4:  "It is an error" => "the consequences are
undefined"?
-------

∂24-Mar-89  1457	X3J13-mailer 	**DRAFT** Issue: PATHNAME-SUBDIRECTORY-LIST (Version 4) 
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 24 Mar 89  14:57:39 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 564943; Fri 24-Mar-89 17:57:27 EST
Date: Fri, 24 Mar 89 17:57 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: **DRAFT** Issue: PATHNAME-SUBDIRECTORY-LIST (Version 4)
To: X3J13@SAIL.STANFORD.EDU
In-Reply-To: <890323155755.4.KMP@BOBOLINK.SCRC.Symbolics.COM>
Message-ID: <19890324225719.7.MOON@EUPHRATES.SCRC.Symbolics.COM>

Due to a lack of coordination on our part, both Kent and I sent
mailings labelled Issue: PATHNAME-SUBDIRECTORY-LIST (Version 4).
The two mailings were quite different.  Kent agrees that the one
he sent should be ignored and the one I sent on Wednesday is the
one you're supposed to read.  Sorry about that.